Author: eliot Date: 2011-01-01 14:45:04 -0800 (Sat, 01 Jan 2011) New Revision: 2339 Modified: branches/Cog/image/VMMaker-Squeak4.1.changes branches/Cog/image/VMMaker-Squeak4.1.image branches/Cog/src/vm/cogit.c branches/Cog/src/vm/cogit.h Log: OSCogVM SimpleStackBasedCogit source as per VMMaker-oscog.42. Fix rounding bug causing underestimate of openPICSize and resultant hard crashes. Modified: branches/Cog/image/VMMaker-Squeak4.1.changes =================================================================== --- branches/Cog/image/VMMaker-Squeak4.1.changes 2011-01-01 20:26:17 UTC (rev 2338) +++ branches/Cog/image/VMMaker-Squeak4.1.changes 2011-01-01 22:45:04 UTC (rev 2339) @@ -151556,4 +151556,55 @@ ----STARTUP----{1 January 2011 . 12:14:25 pm} as /Users/eliot/Cog/oscog/Cog.squeakvm.org/image/VMMaker-Squeak4.1.image! -----QUIT/NOSAVE----{1 January 2011 . 12:15:18 pm} VMMaker-Squeak4.1.image priorSource: 6105162! \ No newline at end of file +----QUIT/NOSAVE----{1 January 2011 . 12:15:18 pm} VMMaker-Squeak4.1.image priorSource: 6105162! + +----STARTUP----{1 January 2011 . 2:27:27 pm} as /Users/eliot/Cog/oscog/Cog.squeakvm.org/image/VMMaker-Squeak4.1.image! + + +| user pw | +Utilities setAuthorInitials. +user := UIManager default request: 'Repository user name'. +pw := UIManager default requestPassword: 'Monticello password'. +MCHttpRepository allSubInstancesDo: [ : rep | + rep user: user; + password: pw ]. +user = 'anon' ifTrue: [MCFileBasedRepository flushAllCaches]! + +'From Squeak4.1 of 17 April 2010 [latest update: #9957] on 1 January 2011 at 2:26:48 pm'! +!Cogit methodsFor: 'initialization' stamp: 'eem 1/1/2011 14:20' prior: 35364073! +generateOpenPICPrototype + "Generate the prototype ClosedPIC to determine how much space as full 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." + | headerSize codeSize mapSize | + "stack allocate the various collections so that they + are effectively garbage collected on return." + self allocateOpcodes: 100 bytecodes: 0. + self compileOpenPIC: 16r5E1EC70 numArgs: self numRegArgs. + self computeMaximumSizes. + headerSize := self sizeof: CogMethod. + methodLabel concretizeAt: methodZoneBase. + codeSize := self generateInstructionsAt: methodZoneBase + headerSize. + mapSize := self generateMapAt: 0 start: methodZoneBase + cmNoCheckEntryOffset. + openPICSize := headerSize + (methodZone roundUpLength: codeSize) + (methodZone roundUpLength: mapSize). + "self cCode: '' + inSmalltalk: + [| end | + end := self outputInstructionsAt: methodZoneBase + headerSize. + self disassembleFrom: methodZoneBase + headerSize to: end - 1. + self halt]"! ! + +----End fileIn of /Users/eliot/Cog/Cogit-generateOpenPICPrototype.st----! + +"VMMaker"! + +| user pw | +Utilities setAuthorInitials. +user := UIManager default request: 'Repository user name'. +pw := UIManager default requestPassword: 'Monticello password'. +MCHttpRepository allSubInstancesDo: [ : rep | + rep user: user; + password: pw ]. +user = 'anon' ifTrue: [MCFileBasedRepository flushAllCaches]! + +----QUIT----{1 January 2011 . 2:37:30 pm} VMMaker-Squeak4.1.image priorSource: 6105162! \ No newline at end of file Modified: branches/Cog/image/VMMaker-Squeak4.1.image =================================================================== (Binary files differ) Modified: branches/Cog/src/vm/cogit.c =================================================================== --- branches/Cog/src/vm/cogit.c 2011-01-01 20:26:17 UTC (rev 2338) +++ branches/Cog/src/vm/cogit.c 2011-01-01 22:45:04 UTC (rev 2339) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker-oscog.41 uuid: 096b8a29-e7e8-4cbf-b29c-0f096abbdd5c + CCodeGenerator VMMaker-oscog.42 uuid: d3b303c1-306e-4343-b078-655fc2bfc436 from - StackToRegisterMappingCogit VMMaker-oscog.41 uuid: 096b8a29-e7e8-4cbf-b29c-0f096abbdd5c + SimpleStackBasedCogit VMMaker-oscog.42 uuid: d3b303c1-306e-4343-b078-655fc2bfc436 */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker-oscog.41 uuid: 096b8a29-e7e8-4cbf-b29c-0f096abbdd5c " __DATE__ ; +static char __buildInfo[] = "SimpleStackBasedCogit VMMaker-oscog.42 uuid: d3b303c1-306e-4343-b078-655fc2bfc436 " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -83,6 +83,14 @@ typedef struct { + AbstractInstruction *targetInstruction; + sqInt instructionIndex; + } BytecodeFixup; + +#define CogBytecodeFixup BytecodeFixup + + +typedef struct { sqInt annotation; AbstractInstruction *instruction; } InstructionAnnotation; @@ -99,35 +107,7 @@ #define CogPrimitiveDescriptor PrimitiveDescriptor -typedef struct { - AbstractInstruction *targetInstruction; - sqInt instructionIndex; - sqInt simStackPtr; - sqInt simSpillBase; - sqInt mergeBase; - sqInt optStatus; - } BytecodeFixup; -#define CogSSBytecodeFixup BytecodeFixup - - -typedef struct { - char type; - char spilled; - sqInt registerr; - sqInt offset; - sqInt constant; - sqInt bcptr; - } CogSimStackEntry; - - -typedef struct { - sqInt isReceiverResultRegLive; - CogSimStackEntry *ssEntry; - } CogSSOptStatus; - - - /*** Constants ***/ #define AddCqR 82 #define AddCwR 89 @@ -143,7 +123,6 @@ #define ArithmeticShiftRightCqR 68 #define ArithmeticShiftRightRR 69 #define BaseHeaderSize 4 -#define BytesPerOop 4 #define BytesPerWord 4 #define Call 8 #define CDQ 102 @@ -164,7 +143,6 @@ #define CmpCwR 88 #define CmpRdRd 95 #define CmpRR 74 -#define ConstZero 1 #define ConvertRRd 101 #define CPUID 105 #define Debug DEBUGVM @@ -198,8 +176,6 @@ #define FoxMFReceiver -12 #define FoxThisContext -8 #define FPReg -1 -#define GPRegMax -3 -#define GPRegMin -8 #define HasBytecodePC 5 #define HashBitsOffset 17 #define HashMaskUnshifted 0xFFF @@ -292,7 +268,7 @@ #define NegateR 67 #define Nop 7 #define NumSendTrampolines 4 -#define NumTrampolines 50 +#define NumTrampolines 38 #define OrCqR 85 #define OrRR 78 #define PopR 62 @@ -318,10 +294,6 @@ #define SizeMask 0xFC #define SPReg -2 #define SqrtRd 100 -#define SSBaseOffset 1 -#define SSConstant 2 -#define SSRegister 3 -#define SSSpill 4 #define StackPointerIndex 2 #define SubCqR 83 #define SubCwR 90 @@ -376,7 +348,6 @@ static AbstractInstruction * annotateobjRef(AbstractInstruction *abstractInstruction, sqInt anOop); static AbstractInstruction * annotatewith(AbstractInstruction *abstractInstruction, sqInt annotationFlag); static void assertSaneJumpTarget(void *jumpTarget); -static sqInt availableRegisterOrNil(void); static sqInt blockCodeSize(unsigned char byteZero, unsigned char byteOne, unsigned char byteTwo, unsigned char byteThree); static sqInt blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg); sqInt bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod); @@ -529,13 +500,8 @@ static sqInt doubleExtendedDoAnythingBytecode(void); static sqInt duplicateTopBytecode(void); static BytecodeFixup * ensureFixupAt(sqInt targetIndex); -static BytecodeFixup * ensureNonMergeFixupAt(sqInt targetIndex); -static void ensureReceiverResultRegContainsSelf(void); -static void ensureSpilledAtfrom(CogSimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister); void enterCogCodePopReceiver(void); void enterCogCodePopReceiverAndClassRegs(void); -void enterCogCodePopReceiverArg0Regs(void); -void enterCogCodePopReceiverArg1Arg0Regs(void); static sqInt extendedPushBytecode(void); static sqInt extendedStoreAndPopBytecode(void); static sqInt extendedStoreBytecode(void); @@ -564,10 +530,8 @@ static sqInt genDoubleArithmeticpreOpCheck(sqInt arithmeticOperator, AbstractInstruction *(*preOpCheckOrNil)(int rcvrReg, int argReg)); static sqInt genDoubleComparisoninvert(AbstractInstruction *(*jumpOpcodeGenerator)(void *), sqInt invertComparison); static AbstractInstruction * genDoubleFailIfZeroArgRcvrarg(sqInt rcvrReg, sqInt argReg); -static void (*genEnilopmartForandandcalled(sqInt regArg1, sqInt regArg2, sqInt regArg3, char *trampolineName))(void) ; static void (*genEnilopmartForandcalled(sqInt regArg1, sqInt regArg2, char *trampolineName))(void) ; static void (*genEnilopmartForcalled(sqInt regArg, char *trampolineName))(void) ; -static void (*genEnterPICEnilopmartNumArgs(sqInt numArgs))(void) ; static sqInt genExtendedSendBytecode(void); static sqInt genExtendedSuperBytecode(void); static sqInt genExternalizePointersForPrimitiveCall(void); @@ -625,16 +589,13 @@ static sqInt genLongJumpIfTrue(void); static sqInt genLongUnconditionalBackwardJump(void); static sqInt genLongUnconditionalForwardJump(void); -static sqInt genMarshalledSendSupernumArgs(sqInt selector, sqInt numArgs); -static sqInt genMarshalledSendnumArgs(sqInt selector, sqInt numArgs); -static sqInt genMethodAbortTrampolineFor(sqInt numArgs); +static sqInt genMethodAbortTrampoline(void); static void genMulRR(AbstractInstruction * self_in_genMulRR, sqInt regSource, sqInt regDest); static sqInt genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName); static sqInt genNonLocalReturnTrampoline(void); static sqInt genPassConstasArgument(AbstractInstruction * self_in_genPassConstasArgument, sqInt constant, sqInt zeroRelativeArgIndex); static sqInt genPassRegasArgument(AbstractInstruction * self_in_genPassRegasArgument, sqInt abstractRegister, sqInt zeroRelativeArgIndex); -static sqInt genPICAbortTrampolineFor(sqInt numArgs); -static sqInt genPICMissTrampolineFor(sqInt numArgs); +static sqInt genPICAbortTrampoline(void); static sqInt genPopStackBytecode(void); static sqInt genPrimitiveAdd(void); static sqInt genPrimitiveAsFloat(void); @@ -689,9 +650,6 @@ static sqInt genPushReceiverBytecode(void); static sqInt genPushReceiverVariableBytecode(void); static sqInt genPushReceiverVariable(sqInt index); -static void genPushRegisterArgs(void); -static void genPushRegisterArgsForAbortMissNumArgs(sqInt numArgs); -static void genPushRegisterArgsForNumArgs(sqInt numArgs); static sqInt genPushRemoteTempLongBytecode(void); static sqInt genPushTemporaryVariableBytecode(void); static sqInt genPushTemporaryVariable(sqInt index); @@ -717,24 +675,19 @@ static sqInt genSendLiteralSelector1ArgBytecode(void); static sqInt genSendLiteralSelector2ArgsBytecode(void); static sqInt genSendSupernumArgs(sqInt selector, sqInt numArgs); -static sqInt genSendTrampolineFornumArgscalledargargargarg(void *aRoutine, sqInt numArgs, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3); static sqInt genSendnumArgs(sqInt selector, sqInt numArgs); static sqInt genSetSmallIntegerTagsIn(sqInt scratchReg); static sqInt genShiftAwaySmallIntegerTagsInScratchReg(sqInt scratchReg); static sqInt genShortJumpIfFalse(void); static sqInt genShortUnconditionalJump(void); static sqInt genSmallIntegerComparison(sqInt jumpOpcode); -static sqInt genSpecialSelectorArithmetic(void); static sqInt genSpecialSelectorClass(void); -static sqInt genSpecialSelectorComparison(void); static sqInt genSpecialSelectorEqualsEquals(void); static sqInt genSpecialSelectorSend(void); -static sqInt genSSPushSlotreg(sqInt index, sqInt baseReg); static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreCheckTrampoline(void); -static sqInt genStoreImmediateInSourceRegslotIndexdestReg(sqInt sourceReg, sqInt index, sqInt destReg); static sqInt genStorePopLiteralVariable(sqInt popBoolean, sqInt litVarIndex); static sqInt genStorePopMaybeContextReceiverVariable(sqInt popBoolean, sqInt slotIndex); static sqInt genStorePopReceiverVariable(sqInt popBoolean, sqInt slotIndex); @@ -746,6 +699,8 @@ static AbstractInstruction * genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc); static sqInt genTrampolineForcalled(void *aRoutine, char *aString); static sqInt genTrampolineForcalledarg(void *aRoutine, char *aString, sqInt regOrConst0); +static sqInt genTrampolineForcalledargarg(void *aRoutine, char *aString, sqInt regOrConst0, sqInt regOrConst1); +static sqInt genTrampolineForcalledargargargarg(void *aRoutine, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3); static sqInt genTrampolineForcalledargargargresult(void *aRoutine, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt resultReg); static sqInt genTrampolineForcalledargargresult(void *aRoutine, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt resultReg); static sqInt genTrampolineForcalledargresult(void *aRoutine, char *aString, sqInt regOrConst0, sqInt resultReg); @@ -771,14 +726,11 @@ static BytecodeFixup * initializeFixupAt(sqInt targetIndex); static sqInt initialMethodUsageCount(void); static sqInt initialOpenPICUsageCount(void); -static void initSimStackForFramefulMethod(sqInt startpc); -static void initSimStackForFramelessMethod(sqInt startpc); static sqInt inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, sqInt callSiteReturnAddress); static sqInt inlineCacheTagForInstance(sqInt oop); static sqInt inlineCacheTagIsYoung(sqInt cacheTag); static sqInt instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc); sqInt interpretOffset(void); -static sqInt inverseBranchFor(sqInt opcode); static sqInt isAFixup(AbstractInstruction * self_in_isAFixup, void *fixupOrAddress); static sqInt isAnInstruction(AbstractInstruction * self_in_isAnInstruction, void *addressOrInstruction); static sqInt isBigEndian(AbstractInstruction * self_in_isBigEndian); @@ -789,7 +741,6 @@ static sqInt isPCDependent(AbstractInstruction * self_in_isPCDependent); static sqInt isQuick(AbstractInstruction * self_in_isQuick, unsigned long operand); sqInt isSendReturnPC(sqInt retpc); -static sqInt isSmallIntegerTagNonZero(void); static AbstractInstruction * gJumpAboveOrEqual(void *jumpTarget); static AbstractInstruction * gJumpAbove(void *jumpTarget); static AbstractInstruction * gJumpBelow(void *jumpTarget); @@ -805,7 +756,6 @@ static AbstractInstruction * gJumpLong(void *jumpTarget); static AbstractInstruction * gJumpNegative(void *jumpTarget); static AbstractInstruction * gJumpNonZero(void *jumpTarget); -static AbstractInstruction * gJumpNoOverflow(void *jumpTarget); static AbstractInstruction * gJumpOverflow(void *jumpTarget); static AbstractInstruction * JumpRT(sqInt callTarget); static AbstractInstruction * gJumpR(sqInt reg); @@ -827,7 +777,6 @@ static sqInt leafCallStackPointerDelta(AbstractInstruction * self_in_leafCallStackPointerDelta); void linkSendAtintocheckedreceiver(sqInt callSiteReturnAddress, CogMethod *sendingMethod, CogMethod *targetMethod, sqInt checked, sqInt receiver); static sqInt literalBeforeFollowingAddress(AbstractInstruction * self_in_literalBeforeFollowingAddress, sqInt followingAddress); -static sqInt liveRegisters(void); static sqInt loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize); static sqInt longBranchDistance(unsigned char byteZero, unsigned char byteOne); static sqInt longForwardBranchDistance(unsigned char byteZero, unsigned char byteOne); @@ -867,14 +816,11 @@ void markMethodAndReferents(CogBlockMethod *aCogMethod); static void markYoungObjectsIn(CogMethod *cogMethod); static sqInt markYoungObjectspcmethod(sqInt annotation, char *mcpc, sqInt cogMethod); -static void marshallSendArguments(sqInt numArgs); usqInt maxCogMethodAddress(void); static sqInt maybeFreeCogMethodDoesntLookKosher(CogMethod *cogMethod); static void maybeGenerateCheckFeatures(void); static void maybeGenerateICacheFlush(void); sqInt mcPCForstartBcpcin(sqInt bcpc, sqInt startbcpc, CogBlockMethod *cogMethod); -static void mergeAtfrom(CogSimStackEntry * self_in_mergeAtfrom, sqInt baseOffset, sqInt baseRegister); -static void mergeafterReturn(BytecodeFixup *fixup, sqInt mergeFollowsReturn); static sqInt methodAbortTrampolineFor(sqInt numArgs); static CogMethod * methodAfter(CogMethod *cogMethod); CogMethod * methodFor(void *address); @@ -882,7 +828,6 @@ sqInt mnuOffset(void); static sqInt modRMRO(AbstractInstruction * self_in_modRMRO, sqInt mod, sqInt regMode, sqInt regOpcode); static AbstractInstruction * gNegateR(sqInt reg); -static AbstractInstruction * gNop(void); static sqInt nextBytecodePCForatbyte0in(BytecodeDescriptor *descriptor, sqInt pc, sqInt opcodeByte, sqInt aMethodObj); static sqInt nextBytecodePCInMapAfterininBlockupTo(sqInt startbcpc, sqInt methodObject, sqInt isInBlock, sqInt endpc); static sqInt noCogMethodsMaximallyMarked(void); @@ -907,7 +852,6 @@ sqInt pcisWithinMethod(char *address, CogMethod *cogMethod); static sqInt picAbortTrampolineFor(sqInt numArgs); static void planCompaction(void); -static void popToReg(CogSimStackEntry * self_in_popToReg, sqInt reg); static PrimitiveDescriptor * primitiveGeneratorOrNil(void); void printCogMethodFor(void *address); void printCogMethods(void); @@ -922,10 +866,7 @@ void recordCallOffsetInof(CogMethod *cogMethod, void *callLabelArg); static void recordGeneratedRunTimeaddress(char *aString, sqInt address); sqInt recordPrimTraceFunc(void); -static sqInt registerMask(CogSimStackEntry * self_in_registerMask); -static sqInt registerMaskFor(sqInt reg); static sqInt registerMaskForandand(sqInt reg1, sqInt reg2, sqInt reg3); -static sqInt registerOrNil(CogSimStackEntry * self_in_registerOrNil); static void relocateAndPruneYoungReferrers(void); static void relocateCallBeforeReturnPCby(AbstractInstruction * self_in_relocateCallBeforeReturnPCby, sqInt retpc, sqInt delta); static void relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); @@ -965,31 +906,10 @@ static sqInt sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress); static sqInt slotOffsetOfInstVarIndex(sqInt index); static sqInt spanForatbyte0in(BytecodeDescriptor *descriptor, sqInt pc, sqInt opcodeByte, sqInt aMethodObj); -static void ssAllocateCallReg(sqInt requiredReg1); -static void ssAllocateCallRegand(sqInt requiredReg1, sqInt requiredReg2); -static sqInt ssAllocatePreferredReg(sqInt preferredReg); -static void ssAllocateRequiredRegMaskupThrough(sqInt requiredRegsMask, sqInt stackPtr); -static void ssAllocateRequiredReg(sqInt requiredReg); -static void ssAllocateRequiredRegand(sqInt requiredReg1, sqInt requiredReg2); -static void ssAllocateRequiredRegupThrough(sqInt requiredReg, sqInt stackPtr); -static void ssFlushTo(sqInt index); -static void ssFlushUpThroughReceiverVariable(sqInt slotIndex); -static void ssFlushUpThroughTemporaryVariable(sqInt tempIndex); -static void ssPop(sqInt n); -static sqInt ssPushBaseoffset(sqInt reg, sqInt offset); -static sqInt ssPushConstant(sqInt literal); -static sqInt ssPushDesc(CogSimStackEntry simStackEntry); -static sqInt ssPushRegister(sqInt reg); -static void ssPush(sqInt n); -static sqInt ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg); -static CogSimStackEntry * ssTop(void); -static CogSimStackEntry ssTopDescriptor(void); -static CogSimStackEntry * ssValue(sqInt n); static sqInt stackBytesForNumArgs(AbstractInstruction * self_in_stackBytesForNumArgs, sqInt numArgs); sqInt stackPageHeadroomBytes(void); static sqInt stackPageInterruptHeadroomBytes(AbstractInstruction * self_in_stackPageInterruptHeadroomBytes); static void storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress); -static void storeToReg(CogSimStackEntry * self_in_storeToReg, sqInt reg); static sqInt sib(AbstractInstruction * self_in_sib, sqInt scale, sqInt indexReg, sqInt baseReg); sqInt traceLinkedSendOffset(void); static char * trampolineNamenumArgs(char *routinePrefix, sqInt numArgs); @@ -1036,7 +956,6 @@ static sqInt bytecodePointer; void * CFramePointer; void * CStackPointer; -static sqInt callerSavedRegMask; sqInt ceBaseFrameReturnTrampoline; sqInt ceCannotResumeTrampoline; void (*ceCaptureCStackPointers)(void); @@ -1045,12 +964,7 @@ static sqInt ceClosureCopyTrampoline; static sqInt ceCPICMissTrampoline; static sqInt ceCreateNewArrayTrampoline; -void (*ceEnter0ArgsPIC)(void); -void (*ceEnter1ArgsPIC)(void); -void (*ceEnter2ArgsPIC)(void); void (*ceEnterCogCodePopReceiverAndClassRegs)(void); -void (*ceEnterCogCodePopReceiverArg0Regs)(void); -void (*ceEnterCogCodePopReceiverArg1Arg0Regs)(void); void (*ceEnterCogCodePopReceiverReg)(void); static sqInt ceFetchContextInstVarTrampoline; static void (*ceFlushICache)(unsigned long from, unsigned long to); @@ -1083,8 +997,6 @@ static sqInt cPICCaseSize; static sqInt cPICEndSize; static const int cStackAlignment = STACK_ALIGN_BYTES; -static sqInt deadCode; -static sqInt debugFixupBreaks; unsigned long debugPrimCallStackOffset; static AbstractInstruction * endCPICCase0; static AbstractInstruction * endCPICCase1; @@ -1099,22 +1011,22 @@ static sqInt firstSend; static BytecodeFixup * fixups; static BytecodeDescriptor generatorTable[256] = { - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, { genPushTemporaryVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, { genPushTemporaryVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, { genPushTemporaryVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, @@ -1211,7 +1123,7 @@ { genStoreAndPopTemporaryVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, { genStoreAndPopTemporaryVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, { genStoreAndPopTemporaryVariableBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, - { genPushReceiverBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { genPushReceiverBytecode, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, { genPushConstantTrueBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { genPushConstantFalseBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { genPushConstantNilBytecode, (sqInt (*)(unsigned char,...))0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, @@ -1275,28 +1187,28 @@ { genLongJumpIfFalse, (sqInt (*)(unsigned char,...))longForwardBranchDistance, 0, 0, 2, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0 }, { genLongJumpIfFalse, (sqInt (*)(unsigned char,...))longForwardBranchDistance, 0, 0, 2, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0 }, { genLongJumpIfFalse, (sqInt (*)(unsigned char,...))longForwardBranchDistance, 0, 0, 2, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0 }, - { genSpecialSelectorArithmetic, (sqInt (*)(unsigned char,...))0, 0, 75, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, - { genSpecialSelectorArithmetic, (sqInt (*)(unsigned char,...))0, 0, 76, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, - { genSpecialSelectorComparison, (sqInt (*)(unsigned char,...))0, 0, 23, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, - { genSpecialSelectorComparison, (sqInt (*)(unsigned char,...))0, 0, 25, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, - { genSpecialSelectorComparison, (sqInt (*)(unsigned char,...))0, 0, 26, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, - { genSpecialSelectorComparison, (sqInt (*)(unsigned char,...))0, 0, 24, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, - { genSpecialSelectorComparison, (sqInt (*)(unsigned char,...))0, 0, 15, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, - { genSpecialSelectorComparison, (sqInt (*)(unsigned char,...))0, 0, 16, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, - { genSpecialSelectorArithmetic, (sqInt (*)(unsigned char,...))0, 0, 77, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, - { genSpecialSelectorArithmetic, (sqInt (*)(unsigned char,...))0, 0, 78, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, + { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, + { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, + { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, + { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, + { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, + { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, + { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, + { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, + { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, + { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, { genSpecialSelectorEqualsEquals, (sqInt (*)(unsigned char,...))0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { genSpecialSelectorClass, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { genSpecialSelectorSend, (sqInt (*)(unsigned char,...))0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0 }, @@ -1365,12 +1277,10 @@ static sqInt lastSend; static usqInt limitAddress; static CogBlockMethod * maxMethodBefore; -static sqInt methodAbortTrampolines[4]; static sqInt methodBytesFreedSinceLastCompaction; static AbstractInstruction *methodLabel = &aMethodLabel; static sqInt methodObj; static sqInt methodOrBlockNumArgs; -static sqInt methodOrBlockNumTemps; static sqInt methodZoneBase; static sqInt missOffset; static AbstractInstruction * mnuCall; @@ -1382,9 +1292,6 @@ static sqInt opcodeIndex; static CogMethod *openPICList = 0; static sqInt openPICSize; -static CogSSOptStatus optStatus; -static sqInt picAbortTrampolines[4]; -static sqInt picMissTrampolines[4]; static void (*postCompileHook)(CogMethod *, void *); static AbstractInstruction * primInvokeLabel; static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] = { @@ -1614,16 +1521,9 @@ }; static sqInt primitiveIndex; void (*realCEEnterCogCodePopReceiverAndClassRegs)(void); -void (*realCEEnterCogCodePopReceiverArg0Regs)(void); -void (*realCEEnterCogCodePopReceiverArg1Arg0Regs)(void); void (*realCEEnterCogCodePopReceiverReg)(void); -static sqInt regArgsHaveBeenPushed; static AbstractInstruction * sendMissCall; static sqInt sendTrampolines[NumSendTrampolines]; -static CogSimStackEntry simSelf; -static sqInt simSpillBase; -static CogSimStackEntry simStack[256]; -static sqInt simStackPtr; static AbstractInstruction * stackCheckLabel; static AbstractInstruction * stackOverflowCall; static sqInt superSendTrampolines[NumSendTrampolines]; @@ -1676,7 +1576,7 @@ #define noCheckEntryOffset() cmNoCheckEntryOffset #define noContextSwitchBlockEntryOffset() blockNoContextSwitchOffset #define notYetImplemented() warning("not yet implemented") -#define numRegArgs() 1 +#define numRegArgs() 0 #define printNum(n) printf("%ld", (long) n) #define printOnTrace() (traceLinkedSends & 8) #define print(aString) printf(aString) @@ -1686,12 +1586,7 @@ #define reportError(n) warning("compilation error") #define setCFramePointer(theFP) (CFramePointer = (void *)(theFP)) #define setCStackPointer(theSP) (CStackPointer = (void *)(theSP)) -#define simStackAt(index) (simStack + (index)) -#define traceDescriptor(ign) 0 -#define traceFixup(ign) 0 #define traceMapbyteatfor(ig,no,re,d) 0 -#define traceMerge(ign) 0 -#define traceSimStack() 0 #define tryLockVMOwner() (ceTryLockVMOwner() != 0) #define typeEtAlWord(cm) (((long *)(cm))[1]) #define unlockVMOwner() ceUnlockVMOwner() @@ -2037,30 +1932,6 @@ } static sqInt -availableRegisterOrNil(void) -{ - sqInt liveRegs; - - liveRegs = liveRegisters(); - if (!(liveRegs & (registerMaskFor(Arg1Reg)))) { - return Arg1Reg; - } - if (!(liveRegs & (registerMaskFor(Arg0Reg)))) { - return Arg0Reg; - } - if (!(liveRegs & (registerMaskFor(SendNumArgsReg)))) { - return SendNumArgsReg; - } - if (!(liveRegs & (registerMaskFor(ClassReg)))) { - return ClassReg; - } - if (!(liveRegs & (registerMaskFor(ReceiverResultReg)))) { - return ReceiverResultReg; - } - return null; -} - -static sqInt blockCodeSize(unsigned char byteZero, unsigned char byteOne, unsigned char byteTwo, unsigned char byteThree) { return (byteTwo * 256) + byteThree; @@ -3126,33 +2997,13 @@ static sqInt compileAbstractInstructionsFromthrough(sqInt start, sqInt end) { - sqInt debugBytecodePointers; BytecodeDescriptor *descriptor; BytecodeFixup *fixup; sqInt nextOpcodeIndex; sqInt result; - traceSimStack(); bytecodePointer = start; - descriptor = null; - deadCode = 0; do { - ; - fixup = fixupAt(bytecodePointer - initialPC); - if ((((usqInt)((fixup->targetInstruction)))) > 0) { - deadCode = 0; - if ((((usqInt)((fixup->targetInstruction)))) >= 2) { - mergeafterReturn(fixup, (descriptor != null) - && ((descriptor->isReturn))); - } - } - else { - if ((descriptor != null) - && ((descriptor->isReturn))) { - deadCode = 1; - } - } - ; byte0 = fetchByteofObject(bytecodePointer, methodObj); descriptor = generatorAt(byte0); if (((descriptor->numBytes)) > 1) { @@ -3168,16 +3019,9 @@ } } nextOpcodeIndex = opcodeIndex; - result = (deadCode - ? (((descriptor->isMapped)) - || (inBlock - && ((descriptor->isMappedInBlock))) - ? annotateBytecode(gNop()) - : 0),0 - : ((descriptor->generator))()); - traceDescriptor(descriptor); - traceSimStack(); - if ((((((usqInt)((fixup->targetInstruction)))) >= 1) && ((((usqInt)((fixup->targetInstruction)))) <= 2))) { + result = ((descriptor->generator))(); + fixup = fixupAt(bytecodePointer - initialPC); + if (((fixup->targetInstruction)) != 0) { if (opcodeIndex == nextOpcodeIndex) { gLabel(); } @@ -3274,18 +3118,12 @@ 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). */ static void compileBlockFrameBuild(BlockStart *blockStart) { AbstractInstruction * cascade0; sqInt i; - sqInt ign; annotateBytecode(gLabel()); gPushR(FPReg); @@ -3306,20 +3144,6 @@ gCmpRR(TempReg, SPReg); gJumpBelow(stackOverflowCall); (blockStart->stackCheckLabel = annotateBytecode(gLabel())); - methodOrBlockNumTemps = (((blockStart->numArgs)) + ((blockStart->numCopied))) + ((blockStart->numInitialNils)); - initSimStackForFramefulMethod((blockStart->startpc)); - if (((blockStart->numInitialNils)) > 0) { - if (((blockStart->numInitialNils)) > 1) { - annotateobjRef(gMoveCwR(nilObject(), TempReg), nilObject()); - for (ign = 1; ign <= ((blockStart->numInitialNils)); ign += 1) { - gPushR(TempReg); - } - } - else { - annotateobjRef(gPushCw(nilObject()), nilObject()); - } - methodOrBlockNumTemps = ((blockStart->numArgs)) + ((blockStart->numCopied)); - } } @@ -3327,14 +3151,10 @@ which is what is initially in ReceiverResultReg. We must annotate the first instruction 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 */ static void compileBlockFramelessEntry(BlockStart *blockStart) { - methodOrBlockNumTemps = ((blockStart->numArgs)) + ((blockStart->numCopied)); - initSimStackForFramelessMethod((blockStart->startpc)); annotateBytecode((blockStart->entryLabel)); annotateBytecode((blockStart->entryLabel)); genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, TempReg); @@ -3375,14 +3195,11 @@ static CogMethod * compileCogMethod(sqInt selector) { - sqInt debugStackPointers; sqInt extra; sqInt numBlocks; sqInt numBytecodes; sqInt result; - methodOrBlockNumTemps = tempCountOf(methodObj); - ; hasYoungReferent = (isYoung(methodObj)) || (isYoung(selector)); methodOrBlockNumArgs = argumentCountOf(methodObj); @@ -3503,9 +3320,6 @@ 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. */ static void compileFrameBuild(void) @@ -3514,13 +3328,8 @@ AbstractInstruction *jumpSkip; if (!(needsFrame)) { - initSimStackForFramelessMethod(initialPC); return; } - genPushRegisterArgs(); - if (!(needsFrame)) { - return; - } gPushR(FPReg); gMoveRR(SPReg, FPReg); addDependent(methodLabel, annotateMethodRef(gPushCw(((sqInt)methodLabel)))); @@ -3547,7 +3356,6 @@ jmpTarget(jumpSkip, stackCheckLabel = gLabel()); } annotateBytecode(stackCheckLabel); - initSimStackForFramefulMethod(initialPC); } @@ -3704,14 +3512,12 @@ /* Compile the abstract instructions for the entire method. */ -/* Compile the abstract instructions for a method. */ static sqInt compileMethod(void) { sqInt result; - regArgsHaveBeenPushed = 0; compileProlog(); compileEntry(); if (((result = compilePrimitive())) < 0) { @@ -3753,7 +3559,7 @@ while (compiledBlocksCount < blockCount) { blockStart = blockStartAt(compiledBlocksCount); compileBlockEntry(blockStart); - if (((result = compileAbstractInstructionsFromthrough(((blockStart->startpc)) + ((blockStart->numInitialNils)), (((blockStart->startpc)) + ((blockStart->span))) - 1))) < 0) { + if (((result = compileAbstractInstructionsFromthrough((blockStart->startpc), (((blockStart->startpc)) + ((blockStart->span))) - 1))) < 0) { return result; } compiledBlocksCount += 1; @@ -3786,7 +3592,7 @@ /* Compile the code for an open PIC. Perform a probe of the first-level method lookup cache followed by a call of ceSendFromOpenPIC: if the probe - fails. Override to push the register args when calling ceSendFromOpenPIC: */ + fails. */ static void compileOpenPICnumArgs(sqInt selector, sqInt numArgs) @@ -3848,7 +3654,6 @@ gCmpRR(SendNumArgsReg, TempReg); gJumpZero(itsAHit); jmpTarget(jumpSelectorMiss, gLabel()); - genPushRegisterArgsForNumArgs(numArgs); genSaveStackPointers(); genLoadCStackPointers(); addDependent(methodLabel, annotateMethodRef(gMoveCwR(((sqInt)methodLabel), SendNumArgsReg))); @@ -6146,7 +5951,7 @@ static sqInt cPICMissTrampolineFor(sqInt numArgs) { - return picMissTrampolines[((numArgs < ((numRegArgs()) + 1)) ? numArgs : ((numRegArgs()) + 1))]; + return ceCPICMissTrampoline; } static sqInt @@ -6538,10 +6343,9 @@ static sqInt duplicateTopBytecode(void) { - CogSimStackEntry desc; - - desc = ssTopDescriptor(); - return ssPushDesc(desc); + gMoveMwrR(0, SPReg, TempReg); + gPushR(TempReg); + return 0; } @@ -6556,93 +6360,13 @@ BytecodeFixup *fixup; fixup = fixupAt(targetIndex); - traceFixup(fixup); - ; - if ((((usqInt)((fixup->targetInstruction)))) <= 1) { - (fixup->targetInstruction = ((AbstractInstruction *) 2)); - (fixup->simStackPtr = simStackPtr); - } - else { - if (((fixup->simStackPtr)) <= -2) { - (fixup->simStackPtr = simStackPtr); - } - else { - assert(((fixup->simStackPtr)) == simStackPtr); - } - } - return fixup; -} - - -/* Make sure there's a flagged fixup at the targetIndex (pc relative to first - pc) in fixups. - Initially a fixup's target is just a flag. Later on it is replaced with a - proper instruction. */ - -static BytecodeFixup * -ensureNonMergeFixupAt(sqInt targetIndex) -{ - BytecodeFixup *fixup; - - fixup = fixupAt(targetIndex); if (((fixup->targetInstruction)) == 0) { (fixup->targetInstruction = ((AbstractInstruction *) 1)); } - ; return fixup; } -static void -ensureReceiverResultRegContainsSelf(void) -{ - if (needsFrame) { - if (!(((optStatus.isReceiverResultRegLive)) - && (((optStatus.ssEntry)) == ((&simSelf))))) { - ssAllocateRequiredReg(ReceiverResultReg); - storeToReg((&simSelf), ReceiverResultReg); - } - (optStatus.isReceiverResultRegLive = 1); - (optStatus.ssEntry = (&simSelf)); - } - else { - assert((((simSelf.type)) == SSRegister) - && (((simSelf.registerr)) == ReceiverResultReg)); - assert(((optStatus.isReceiverResultRegLive)) - && (((optStatus.ssEntry)) == ((&simSelf)))); - } -} -static void -ensureSpilledAtfrom(CogSimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister) -{ - if ((self_in_ensureSpilledAtfrom->spilled)) { - if (((self_in_ensureSpilledAtfrom->type)) == SSSpill) { - assert((((self_in_ensureSpilledAtfrom->offset)) == baseOffset) - && (((self_in_ensureSpilledAtfrom->registerr)) == baseRegister)); - return; - } - } - assert(((self_in_ensureSpilledAtfrom->type)) != SSSpill); - if (((self_in_ensureSpilledAtfrom->type)) == SSConstant) { - annotateobjRef(gPushCw((self_in_ensureSpilledAtfrom->constant)), (self_in_ensureSpilledAtfrom->constant)); - } - else { - if (((self_in_ensureSpilledAtfrom->type)) == SSBaseOffset) { - gMoveMwrR((self_in_ensureSpilledAtfrom->offset), (self_in_ensureSpilledAtfrom->registerr), TempReg); - gPushR(TempReg); - } - else { - assert(((self_in_ensureSpilledAtfrom->type)) == SSRegister); - gPushR((self_in_ensureSpilledAtfrom->registerr)); - } - (self_in_ensureSpilledAtfrom->type) = SSSpill; - (self_in_ensureSpilledAtfrom->offset) = baseOffset; - (self_in_ensureSpilledAtfrom->registerr) = baseRegister; - } - (self_in_ensureSpilledAtfrom->spilled) = 1; -} - - /* This is a static version of ceEnterCogCodePopReceiverReg for break-pointing when debugging in C. */ /* (and this exists only to reference Debug) */ @@ -6670,34 +6394,6 @@ realCEEnterCogCodePopReceiverAndClassRegs(); } - -/* This is a static version of ceEnterCogCodePopReceiverArg0Regs - for break-pointing when debugging in C. */ -/* (and this exists only to reference Debug) */ - -void -enterCogCodePopReceiverArg0Regs(void) -{ - if (!(Debug)) { - error("what??"); - } - realCEEnterCogCodePopReceiverArg0Regs(); -} - - -/* This is a static version of ceEnterCogCodePopReceiverArg1Arg0Regs - for break-pointing when debugging in C. */ -/* (and this exists only to reference Debug) */ - -void -enterCogCodePopReceiverArg1Arg0Regs(void) -{ - if (!(Debug)) { - error("what??"); - } - realCEEnterCogCodePopReceiverArg1Arg0Regs(); -} - static sqInt extendedPushBytecode(void) { @@ -7239,27 +6935,29 @@ } -/* Receiver and arg in registers. - Stack looks like +/* Stack looks like + receiver (also in ResultReceiverReg) + arg return address */ static sqInt genDoubleArithmeticpreOpCheck(sqInt arithmeticOperator, AbstractInstruction *(*preOpCheckOrNil)(int rcvrReg, int argReg)) { AbstractInstruction *doOp; + AbstractInstruction *fail; AbstractInstruction *jumpFailAlloc; AbstractInstruction *jumpFailCheck; AbstractInstruction *jumpFailClass; AbstractInstruction *jumpSmallInt; - gMoveRR(Arg0Reg, TempReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); genGetDoubleValueOfinto(ReceiverResultReg, DPFPReg0); - gMoveRR(Arg0Reg, ClassReg); + gMoveRR(TempReg, ClassReg); jumpSmallInt = genJumpSmallIntegerInScratchReg(TempReg); - genGetCompactClassIndexNonIntOfinto(Arg0Reg, SendNumArgsReg); + genGetCompactClassIndexNonIntOfinto(ClassReg, SendNumArgsReg); gCmpCqR(classFloatCompactIndex(), SendNumArgsReg); jumpFailClass = gJumpNonZero(0); - genGetDoubleValueOfinto(Arg0Reg, DPFPReg1); + genGetDoubleValueOfinto(ClassReg, DPFPReg1); doOp = gLabel(); if (preOpCheckOrNil == null) { null; @@ -7270,30 +6968,29 @@ genoperandoperand(arithmeticOperator, DPFPReg1, DPFPReg0); jumpFailAlloc = genAllocFloatValueintoscratchRegscratchReg(DPFPReg0, SendNumArgsReg, ClassReg, TempReg); gMoveRR(SendNumArgsReg, ReceiverResultReg); - gRetN(0); - assert(methodOrBlockNumArgs <= (numRegArgs())); - jmpTarget(jumpFailClass, gLabel()); - if (preOpCheckOrNil == null) { - null; - } - else { - jmpTarget(jumpFailCheck, getJmpTarget(jumpFailClass)); - } - genPushRegisterArgsForNumArgs(methodOrBlockNumArgs); - jumpFailClass = gJump(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpSmallInt, gLabel()); genConvertSmallIntegerToIntegerInScratchReg(ClassReg); gConvertRRd(ClassReg, DPFPReg1); gJump(doOp); jmpTarget(jumpFailAlloc, gLabel()); compileInterpreterPrimitive(functionPointerForCompiledMethodprimitiveIndex(methodObj, primitiveIndex)); + fail = gLabel(); jmpTarget(jumpFailClass, gLabel()); + if (preOpCheckOrNil == null) { + null; + } + else { + jmpTarget(jumpFailCheck, fail); + } return 0; } -/* Receiver and arg in registers. - Stack looks like +/* Stack looks like + receiver (also in ResultReceiverReg) + arg return address */ static sqInt @@ -7304,13 +7001,14 @@ AbstractInstruction *jumpFail; AbstractInstruction *jumpSmallInt; - gMoveRR(Arg0Reg, TempReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); genGetDoubleValueOfinto(ReceiverResultReg, DPFPReg0); + gMoveRR(TempReg, ClassReg); jumpSmallInt = genJumpSmallIntegerInScratchReg(TempReg); - genGetCompactClassIndexNonIntOfinto(Arg0Reg, SendNumArgsReg); + genGetCompactClassIndexNonIntOfinto(ClassReg, SendNumArgsReg); gCmpCqR(classFloatCompactIndex(), SendNumArgsReg); jumpFail = gJumpNonZero(0); - genGetDoubleValueOfinto(Arg0Reg, DPFPReg1); + genGetDoubleValueOfinto(ClassReg, DPFPReg1); if (invertComparison) { /* May need to invert for NaNs */ @@ -7325,12 +7023,13 @@ jumpCond = jumpOpcodeGenerator(0); annotateobjRef(gMoveCwR(falseObject(), ReceiverResultReg), falseObject()); - gRetN(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpCond, annotateobjRef(gMoveCwR(trueObject(), ReceiverResultReg), trueObject())); - gRetN(0); + gRetN(BytesPerWord * 2); jmpTarget(jumpSmallInt, gLabel()); - genConvertSmallIntegerToIntegerInScratchReg(Arg0Reg); - gConvertRRd(Arg0Reg, DPFPReg1); + genConvertSmallIntegerToIntegerInScratchReg(ClassReg); + gConvertRRd(ClassReg, DPFPReg1); gJump(compare); jmpTarget(jumpFail, gLabel()); return 0; @@ -7353,38 +7052,6 @@ then executes a return instruction to pop off the entry-point and jump to it. */ -static void (*genEnilopmartForandandcalled(sqInt regArg1, sqInt regArg2, sqInt regArg3, char *trampolineName))(void) - -{ - sqInt endAddress; - sqInt enilopmart; - sqInt size; - - opcodeIndex = 0; - genLoadStackPointers(); - gPopR(regArg3); - gPopR(regArg2); - gPopR(regArg1); - gRetN(0); - computeMaximumSizes(); - size = generateInstructionsAt(methodZoneBase); - endAddress = outputInstructionsAt(methodZoneBase); - assert((methodZoneBase + size) == endAddress); - enilopmart = methodZoneBase; - methodZoneBase = alignUptoRoutineBoundary(endAddress); - nopsFromto(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. 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. */ - static void (*genEnilopmartForandcalled(sqInt regArg1, sqInt regArg2, char *trampolineName))(void) { @@ -7439,44 +7106,6 @@ } -/* Generate special versions of the ceEnterCogCodePopReceiverAndClassRegs - enilopmart that also pop register args from the stack to undo the pushing - of register args in the abort/miss trampolines. */ - -static void (*genEnterPICEnilopmartNumArgs(sqInt numArgs))(void) - -{ - sqInt endAddress; - sqInt enilopmart; - sqInt size; - - opcodeIndex = 0; - genLoadStackPointers(); - gPopR(ClassReg); - gPopR(TempReg); - gPopR(SendNumArgsReg); - if (numArgs > 0) { - if (numArgs > 1) { - gPopR(Arg1Reg); - assert((numRegArgs()) == 2); - } - gPopR(Arg0Reg); - } - gPopR(ReceiverResultReg); - gPushR(SendNumArgsReg); - gJumpR(TempReg); - computeMaximumSizes(); - size = generateInstructionsAt(methodZoneBase); - endAddress = outputInstructionsAt(methodZoneBase); - assert((methodZoneBase + size) == endAddress); - enilopmart = methodZoneBase; - methodZoneBase = alignUptoRoutineBoundary(endAddress); - nopsFromto(backEnd, endAddress, methodZoneBase - 1); - recordGeneratedRunTimeaddress(trampolineNamenumArgs("ceEnterPIC", numArgs), enilopmart); - return ((void (*)(void)) enilopmart); -} - - /* Can use any of the first 32 literals for the selector and pass up to 7 arguments. */ @@ -7493,13 +7122,9 @@ return genSendSupernumArgs(literalofMethod(byte1 & 31, methodObj), ((usqInt) byte1) >> 5); } - -/* Override to push the register receiver and register arguments, if any. */ - static sqInt genExternalizePointersForPrimitiveCall(void) { - genPushRegisterArgs(); gMoveMwrR(0, SPReg, ClassReg); gMoveRAw(FPReg, framePointerAddress()); gLoadEffectiveAddressMwrR(BytesPerWord, SPReg, TempReg); @@ -7683,9 +7308,6 @@ /* 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. */ static void generateEnilopmarts(void) @@ -7711,27 +7333,6 @@ cePrimReturnEnterCogCodeProfiling = methodZoneBase; outputInstructionsForGeneratedRuntimeAt(cePrimReturnEnterCogCodeProfiling); recordGeneratedRunTimeaddress("cePrimReturnEnterCogCodeProfiling", cePrimReturnEnterCogCodeProfiling); - -# if Debug - realCEEnterCogCodePopReceiverArg0Regs = genEnilopmartForandcalled(ReceiverResultReg, Arg0Reg, "realCEEnterCogCodePopReceiverArg0Regs"); - ceEnterCogCodePopReceiverArg0Regs = enterCogCodePopReceiverArg0Regs; - realCEEnterCogCodePopReceiverArg1Arg0Regs = genEnilopmartForandandcalled(ReceiverResultReg, Arg0Reg, Arg1Reg, "realCEEnterCogCodePopReceiverArg1Arg0Regs"); - ceEnterCogCodePopReceiverArg1Arg0Regs = enterCogCodePopReceiverArg1Arg0Regs; - -# else /* Debug */ - ceEnterCogCodePopReceiverArg0Regs = genEnilopmartForandcalled(ReceiverResultReg, Arg0Reg, "ceEnterCogCodePopReceiverArg0Regs"); - ceEnterCogCodePopReceiverArg1Arg0Regs = genEnilopmartForandandcalled(ReceiverResultReg, Arg0Reg, Arg1Reg, "ceEnterCogCodePopReceiverArg1Arg0Regs"); - -# endif /* Debug */ - - ceEnter0ArgsPIC = genEnterPICEnilopmartNumArgs(0); - if ((numRegArgs()) >= 1) { - ceEnter1ArgsPIC = genEnterPICEnilopmartNumArgs(1); - if ((numRegArgs()) >= 2) { - ceEnter1ArgsPIC = genEnterPICEnilopmartNumArgs(2); - assert((numRegArgs()) == 2); - } - } } @@ -7886,17 +7487,9 @@ static void generateMissAbortTrampolines(void) { - sqInt numArgs; - - for (numArgs = 0; numArgs <= ((numRegArgs()) + 1); numArgs += 1) { - methodAbortTrampolines[numArgs] = (genMethodAbortTrampolineFor(numArgs)); - } - for (numArgs = 0; numArgs <= ((numRegArgs()) + 1); numArgs += 1) { - picAbortTrampolines[numArgs] = (genPICAbortTrampolineFor(numArgs)); - } - for (numArgs = 0; numArgs <= ((numRegArgs()) + 1); numArgs += 1) { - picMissTrampolines[numArgs] = (genPICMissTrampolineFor(numArgs)); - } + ceMethodAbortTrampoline = genMethodAbortTrampoline(); + cePICAbortTrampoline = genPICAbortTrampoline(); + ceCPICMissTrampoline = genTrampolineForcalledargarg(ceCPICMissreceiver, "ceCPICMissTrampoline", ClassReg, ReceiverResultReg); ; } @@ -7916,13 +7509,13 @@ sqInt mapSize; allocateOpcodesbytecodes(100, 0); - compileOpenPICnumArgs(98692208, 0); + compileOpenPICnumArgs(98692208, numRegArgs()); computeMaximumSizes(); headerSize = sizeof(CogMethod); concretizeAt(methodLabel, methodZoneBase); codeSize = generateInstructionsAt(methodZoneBase + headerSize); mapSize = generateMapAtstart(0, methodZoneBase + cmNoCheckEntryOffset); - openPICSize = roundUpLength((headerSize + codeSize) + mapSize); + openPICSize = (headerSize + (roundUpLength(codeSize))) + (roundUpLength(mapSize)); } @@ -7956,9 +7549,6 @@ } -/* Override to generate code to push the register arg(s) for <= numRegArg - arity sends. - */ /* Slang needs these apparently superfluous asSymbol sends. */ static void @@ -7967,13 +7557,13 @@ sqInt numArgs; for (numArgs = 0; numArgs <= (NumSendTrampolines - 2); numArgs += 1) { - sendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, numArgs, trampolineNamenumArgs("ceSend", numArgs), ClassReg, 0, ReceiverResultReg, numArgs)); + sendTrampolines[numArgs] = (genTrampolineForcalledargargargarg(ceSendsupertonumArgs, trampolineNamenumArgs("ceSend", numArgs), ClassReg, 0, ReceiverResultReg, numArgs)); } - sendTrampolines[NumSendTrampolines - 1] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, (numRegArgs()) + 1, trampolineNamenumArgs("ceSend", -1), ClassReg, 0, ReceiverResultReg, SendNumArgsReg)); + sendTrampolines[NumSendTrampolines - 1] = (genTrampolineForcalledargargargarg(ceSendsupertonumArgs, trampolineNamenumArgs("ceSend", -1), ClassReg, 0, ReceiverResultReg, SendNumArgsReg)); for (numArgs = 0; numArgs <= (NumSendTrampolines - 2); numArgs += 1) { - superSendTrampolines[numArgs] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, numArgs, trampolineNamenumArgs("ceSuperSend", numArgs), ClassReg, 1, ReceiverResultReg, numArgs)); + superSendTrampolines[numArgs] = (genTrampolineForcalledargargargarg(ceSendsupertonumArgs, trampolineNamenumArgs("ceSuperSend", numArgs), ClassReg, 1, ReceiverResultReg, numArgs)); } - superSendTrampolines[NumSendTrampolines - 1] = (genSendTrampolineFornumArgscalledargargargarg(ceSendsupertonumArgs, (numRegArgs()) + 1, trampolineNamenumArgs("ceSuperSend", -1), ClassReg, 1, ReceiverResultReg, SendNumArgsReg)); + superSendTrampolines[NumSendTrampolines - 1] = (genTrampolineForcalledargargargarg(ceSendsupertonumArgs, trampolineNamenumArgs("ceSuperSend", -1), ClassReg, 1, ReceiverResultReg, SendNumArgsReg)); firstSend = sendTrampolines[0]; lastSend = superSendTrampolines[NumSendTrampolines - 1]; } @@ -8013,7 +7603,7 @@ { ceTraceLinkedSendTrampoline = genSafeTrampolineForcalledarg(ceTraceLinkedSend, "ceTraceLinkedSendTrampoline", ReceiverResultReg); ceTraceBlockActivationTrampoline = genTrampolineForcalled(ceTraceBlockActivation, "ceTraceBlockActivationTrampoline"); - ceTraceStoreTrampoline = genSafeTrampolineForcalledargarg(ceTraceStoreOfinto, "ceTraceStoreTrampoline", TempReg, ReceiverResultReg); + ceTraceStoreTrampoline = genSafeTrampolineForcalledargarg(ceTraceStoreOfinto, "ceTraceStoreTrampoline", ClassReg, ReceiverResultReg); } @@ -8483,7 +8073,6 @@ static sqInt genJumpBackTo(sqInt targetBytecodePC) { - ssFlushTo(simStackPtr); gMoveAwR(stackLimitAddress(), TempReg); gCmpRR(TempReg, SPReg); gJumpAboveOrEqual(fixupAt(targetBytecodePC - initialPC)); @@ -8540,25 +8129,19 @@ return jumpToTarget; } + +/* 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. */ + static sqInt genJumpIfto(sqInt boolean, sqInt targetBytecodePC) { - CogSimStackEntry *desc; AbstractInstruction *ok; - ssFlushTo(simStackPtr - 1); - desc = ssTop(); - ssPop(1); - if ((((desc->type)) == SSConstant) - && ((((desc->constant)) == (trueObject())) - || (((desc->constant)) == (falseObject())))) { - annotateBytecode((((desc->constant)) == boolean - ? gJump(ensureFixupAt(targetBytecodePC - initialPC)) - : gLabel())); - return 0; - } - popToReg(desc, TempReg); assert((objectAfter(falseObject())) == (trueObject())); + gPopR(TempReg); annotateobjRef(gSubCwR(boolean, TempReg), boolean); gJumpZero(ensureFixupAt(targetBytecodePC - initialPC)); gCmpCqR((boolean == (falseObject()) @@ -8589,7 +8172,6 @@ static sqInt genJumpTo(sqInt targetBytecodePC) { - ssFlushTo(simStackPtr); gJump(ensureFixupAt(targetBytecodePC - initialPC)); return 0; } @@ -8686,39 +8268,7 @@ return genJumpTo(targetpc); } -static sqInt -genMarshalledSendSupernumArgs(sqInt selector, sqInt numArgs) -{ - if (isYoung(selector)) { - hasYoungReferent = 1; - } - assert(needsFrame); - if (numArgs > 2) { - gMoveCqR(numArgs, SendNumArgsReg); - } - gMoveCwR(selector, ClassReg); - CallSend(superSendTrampolines[((numArgs < (NumSendTrampolines - 1)) ? numArgs : (NumSendTrampolines - 1))]); - (optStatus.isReceiverResultRegLive = 0); - return ssPushRegister(ReceiverResultReg); -} -static sqInt -genMarshalledSendnumArgs(sqInt selector, sqInt numArgs) -{ - if (isYoung(selector)) { - hasYoungReferent = 1; - } - assert(needsFrame); - if (numArgs > 2) { - gMoveCqR(numArgs, SendNumArgsReg); - } - gMoveCwR(selector, ClassReg); - CallSend(sendTrampolines[((numArgs < (NumSendTrampolines - 1)) ? numArgs : (NumSendTrampolines - 1))]); - (optStatus.isReceiverResultRegLive = 0); - 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 @@ -8730,7 +8280,7 @@ miss. */ static sqInt -genMethodAbortTrampolineFor(sqInt numArgs) +genMethodAbortTrampoline(void) { AbstractInstruction *jumpSICMiss; @@ -8739,10 +8289,7 @@ jumpSICMiss = gJumpNonZero(0); compileTrampolineForcallJumpBarnumArgsargargargargsaveRegsresultReg(ceStackOverflow, 1, 1, SendNumArgsReg, null, null, null, 0, null); jmpTarget(jumpSICMiss, gLabel()); - genPushRegisterArgsForAbortMissNumArgs(numArgs); - return genTrampolineForcalledcallJumpBarnumArgsargargargargsaveRegsresultRegappendOpcodes(ceSICMiss, trampolineNamenumArgs("ceMethodAbort", (numArgs <= (numRegArgs()) - ? numArgs - : -1)), 1, 1, ReceiverResultReg, null, null, null, 0, null, 1); + return genTrampolineForcalledcallJumpBarnumArgsargargargargsaveRegsresultRegappendOpcodes(ceSICMiss, "ceMethodAbort", 1, 1, ReceiverResultReg, null, null, null, 0, null, 1); } static void @@ -8795,71 +8342,62 @@ ClassReg. If the register is zero then this is an MNU. */ static sqInt -genPICAbortTrampolineFor(sqInt numArgs) +genPICAbortTrampoline(void) { opcodeIndex = 0; - genPushRegisterArgsForAbortMissNumArgs(numArgs); - return genInnerPICAbortTrampoline(trampolineNamenumArgs("cePICAbort", (numArgs <= (numRegArgs()) - ? numArgs - : -1))); + return genInnerPICAbortTrampoline("cePICAbort"); } static sqInt -genPICMissTrampolineFor(sqInt numArgs) -{ - sqInt startAddress; - - startAddress = methodZoneBase; - - /* N.B. a closed PIC jumps to the miss routine, not calls it, so there is only one retpc on the stack. */ - - opcodeIndex = 0; - genPushRegisterArgsForNumArgs(numArgs); - genTrampolineForcalledcallJumpBarnumArgsargargargargsaveRegsresultRegappendOpcodes(ceCPICMissreceiver, trampolineNamenumArgs("cePICMiss", (numArgs <= (numRegArgs()) - ? numArgs - : -1)), 1, 2, ClassReg, ReceiverResultReg, null, null, 0, null, 1); - return startAddress; -} - -static sqInt genPopStackBytecode(void) { - if ((ssTop()->spilled)) { - gAddCqR(BytesPerWord, SPReg); - } - ssPop(1); + gAddCqR(BytesPerWord, SPReg); return 0; } + +/* Stack looks like + receiver (also in ResultReceiverReg) + arg + return address */ + static sqInt genPrimitiveAdd(void) { AbstractInstruction *jumpNotSI; AbstractInstruction *jumpOvfl; - gMoveRR(Arg0Reg, TempReg); - gMoveRR(Arg0Reg, ClassReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gMoveRR(TempReg, ClassReg); jumpNotSI = genJumpNotSmallIntegerInScratchReg(TempReg); genRemoveSmallIntegerTagsInScratchReg(ClassReg); - gAddRR(ReceiverResultReg, ClassReg); + gMoveRR(ReceiverResultReg, TempReg); + gAddRR(ClassReg, TempReg); jumpOvfl = gJumpOverflow(0); - gMoveRR(ClassReg, ReceiverResultReg); - gRetN(0); + gMoveRR(TempReg, ReceiverResultReg); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, gLabel())); return 0; } + +/* Stack looks like + receiver (also in ResultReceiverReg) + return address */ + static sqInt genPrimitiveAsFloat(void) { AbstractInstruction *jumpFailAlloc; - gMoveRR(ReceiverResultReg, TempReg); - genConvertSmallIntegerToIntegerInScratchReg(TempReg); - gConvertRRd(TempReg, DPFPReg0); + gMoveRR(ReceiverResultReg, ClassReg); + genConvertSmallIntegerToIntegerInScratchReg(ClassReg); + gConvertRRd(ClassReg, DPFPReg0); jumpFailAlloc = genAllocFloatValueintoscratchRegscratchReg(DPFPReg0, SendNumArgsReg, ClassReg, TempReg); gMoveRR(SendNumArgsReg, ReceiverResultReg); - gRetN(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord); jmpTarget(jumpFailAlloc, gLabel()); compileInterpreterPrimitive(functionPointerForCompiledMethodprimitiveIndex(methodObj, primitiveIndex)); return 0; @@ -8868,8 +8406,8 @@ static sqInt genPrimitiveAt(void) { - assert((numRegArgs()) >= 1); - return genInnerPrimitiveAt(0); + gMoveMwrR(BytesPerWord, SPReg, Arg0Reg); + return genInnerPrimitiveAt(BytesPerWord * 2); } static sqInt @@ -8877,13 +8415,15 @@ { AbstractInstruction *jumpNotSI; - gMoveRR(Arg0Reg, TempReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gMoveRR(TempReg, ClassReg); - /* Whether the SmallInteger tags are zero or non-zero, oring them together will preserve them. */ + /* Whether the SmallInteger tags are zero or non-zero, anding them together will preserve them. */ jumpNotSI = genJumpNotSmallIntegerInScratchReg(TempReg); - gAndRR(Arg0Reg, ReceiverResultReg); - gRetN(0); + gAndRR(ClassReg, ReceiverResultReg); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpNotSI, gLabel()); return 0; } @@ -8893,23 +8433,26 @@ { AbstractInstruction *jumpNotSI; - gMoveRR(Arg0Reg, TempReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gMoveRR(TempReg, ClassReg); /* Whether the SmallInteger tags are zero or non-zero, oring them together will preserve them. */ jumpNotSI = genJumpNotSmallIntegerInScratchReg(TempReg); - gOrRR(Arg0Reg, ReceiverResultReg); - gRetN(0); + gOrRR(ClassReg, ReceiverResultReg); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpNotSI, gLabel()); return 0; } -/* Receiver and arg in registers. - Stack looks like +/* Stack looks like + receiver (also in ResultReceiverReg) + arg return address - rTemp := rArg0 + rTemp := ArgOffset(SP) rClass := tTemp rTemp := rTemp & 1 jz nonInt @@ -8951,9 +8494,8 @@ AbstractInstruction *jumpOvfl; AbstractInstruction *jumpTooBig; - assert((numRegArgs()) >= 1); - gMoveRR(Arg0Reg, TempReg); - gMoveRR(Arg0Reg, ClassReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gMoveRR(TempReg, ClassReg); jumpNotSI = genJumpNotSmallIntegerInScratchReg(TempReg); genConvertSmallIntegerToIntegerInScratchReg(ClassReg); if (!(setsConditionCodesFor(lastOpcode(), JumpNegative))) { @@ -8970,14 +8512,14 @@ genRemoveSmallIntegerTagsInScratchReg(ReceiverResultReg); gLogicalShiftLeftRR(ClassReg, ReceiverResultReg); genAddSmallIntegerTagsTo(ReceiverResultReg); - gRetN(0); + gRetN(BytesPerWord * 2); jmpTarget(jumpNegative, gNegateR(ClassReg)); gCmpCqR(numSmallIntegerBits(), ClassReg); jumpInRange = gJumpLessOrEqual(0); gMoveCqR(numSmallIntegerBits(), ClassReg); jmpTarget(jumpInRange, gArithmeticShiftRightRR(ClassReg, ReceiverResultReg)); genSetSmallIntegerTagsIn(ReceiverResultReg); - gRetN(0); + gRetN(BytesPerWord * 2); jmpTarget(jumpNotSI, jmpTarget(jumpTooBig, jmpTarget(jumpOvfl, gLabel()))); return 0; } @@ -8987,14 +8529,16 @@ { AbstractInstruction *jumpNotSI; - gMoveRR(Arg0Reg, TempReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gMoveRR(TempReg, ClassReg); /* Clear one or the other tag so that xoring will preserve them. */ jumpNotSI = genJumpNotSmallIntegerInScratchReg(TempReg); - genRemoveSmallIntegerTagsInScratchReg(Arg0Reg); - gXorRR(Arg0Reg, ReceiverResultReg); - gRetN(0); + genRemoveSmallIntegerTagsInScratchReg(ClassReg); + gXorRR(ClassReg, ReceiverResultReg); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpNotSI, gLabel()); return 0; } @@ -9006,13 +8550,6 @@ 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. */ static sqInt genPrimitiveClosureValue(void) @@ -9022,7 +8559,6 @@ void (*primitiveRoutine)(); sqInt result; - genPushRegisterArgs(); genLoadSlotsourceRegdestReg(ClosureNumArgsIndex, ReceiverResultReg, TempReg); gCmpCqR(((methodOrBlockNumArgs << 1) | 1), TempReg); jumpFail = gJumpNonZero(0); @@ -9055,9 +8591,9 @@ AbstractInstruction *jumpSameSign; AbstractInstruction *jumpZero; - gMoveRR(Arg0Reg, TempReg); - gMoveRR(Arg0Reg, ClassReg); - gMoveRR(Arg0Reg, Arg1Reg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gMoveRR(TempReg, ClassReg); + gMoveRR(TempReg, Arg1Reg); /* We must shift away the tags, not just subtract them, so that the overflow case doesn't actually overflow the machine instruction. */ @@ -9085,7 +8621,8 @@ jmpTarget(jumpSameSign, convert = gLabel()); genConvertIntegerToSmallIntegerInScratchReg(TempReg); gMoveRR(TempReg, ReceiverResultReg); - gRetN(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpExact, gCmpCqR(1 << ((numSmallIntegerBits()) - 1), TempReg)); gJumpLess(convert); jmpTarget(jumpZero, jmpTarget(jumpNotSI, gLabel())); @@ -9100,8 +8637,8 @@ AbstractInstruction *jumpOverflow; AbstractInstruction *jumpZero; - gMoveRR(Arg0Reg, TempReg); - gMoveRR(Arg0Reg, ClassReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gMoveRR(TempReg, ClassReg); /* We must shift away the tags, not just subtract them, so that the overflow case doesn't actually overflow the machine instruction. */ @@ -9121,7 +8658,8 @@ jumpOverflow = gJumpGreaterOrEqual(0); genConvertIntegerToSmallIntegerInScratchReg(TempReg); gMoveRR(TempReg, ReceiverResultReg); - gRetN(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpOverflow, jmpTarget(jumpInexact, jmpTarget(jumpZero, jmpTarget(jumpNotSI, gLabel())))); return 0; } @@ -9133,8 +8671,9 @@ } -/* Receiver and arg in registers. - Stack looks like +/* Stack looks like + receiver (also in ResultReceiverReg) + arg return address */ static sqInt @@ -9142,12 +8681,14 @@ { AbstractInstruction *jumpFalse; - gCmpRR(Arg0Reg, ReceiverResultReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gCmpRR(TempReg, ReceiverResultReg); jumpFalse = gJumpNonZero(0); annotateobjRef(gMoveCwR(trueObject(), ReceiverResultReg), trueObject()); - gRetN(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpFalse, annotateobjRef(gMoveCwR(falseObject(), ReceiverResultReg), falseObject())); - gRetN(0); + gRetN(BytesPerWord * 2); return 0; } @@ -9205,6 +8746,11 @@ return genDoubleComparisoninvert(gJumpFPNotEqual, 0); } + +/* Stack looks like + receiver (also in ResultReceiverReg) + return address */ + static sqInt genPrimitiveFloatSquareRoot(void) { @@ -9214,7 +8760,8 @@ gSqrtRd(DPFPReg0); jumpFailAlloc = genAllocFloatValueintoscratchRegscratchReg(DPFPReg0, SendNumArgsReg, ClassReg, TempReg); gMoveRR(SendNumArgsReg, ReceiverResultReg); - gRetN(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord); jmpTarget(jumpFailAlloc, gLabel()); compileInterpreterPrimitive(functionPointerForCompiledMethodprimitiveIndex(methodObj, primitiveIndex)); return 0; @@ -9247,7 +8794,8 @@ jumpSI = genJumpSmallIntegerInScratchReg(ClassReg); genGetHashFieldNonIntOfasSmallIntegerInto(ReceiverResultReg, TempReg); gMoveRR(TempReg, ReceiverResultReg); - gRetN(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord); jmpTarget(jumpSI, gLabel()); return 0; } @@ -9272,8 +8820,8 @@ AbstractInstruction *jumpSameSign; AbstractInstruction *jumpZero; - gMoveRR(Arg0Reg, TempReg); - gMoveRR(Arg0Reg, ClassReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gMoveRR(TempReg, ClassReg); jumpNotSI = genJumpNotSmallIntegerInScratchReg(TempReg); genRemoveSmallIntegerTagsInScratchReg(ClassReg); jumpZero = gJumpZero(0); @@ -9296,7 +8844,8 @@ jmpTarget(jumpSameSign, jmpTarget(jumpExact, gLabel())); genSetSmallIntegerTagsIn(ClassReg); gMoveRR(ClassReg, ReceiverResultReg); - gRetN(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpZero, jmpTarget(jumpNotSI, gLabel())); return 0; } @@ -9307,17 +8856,18 @@ AbstractInstruction *jumpNotSI; AbstractInstruction *jumpOvfl; - gMoveRR(Arg0Reg, TempReg); - gMoveRR(Arg0Reg, ClassReg); - gMoveRR(ReceiverResultReg, Arg1Reg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gMoveRR(TempReg, ClassReg); jumpNotSI = genJumpNotSmallIntegerInScratchReg(TempReg); genShiftAwaySmallIntegerTagsInScratchReg(ClassReg); - genRemoveSmallIntegerTagsInScratchReg(Arg1Reg); - gMulRR(Arg1Reg, ClassReg); + gMoveRR(ReceiverResultReg, TempReg); + genRemoveSmallIntegerTagsInScratchReg(TempReg); + gMulRR(TempReg, ClassReg); jumpOvfl = gJumpOverflow(0); genSetSmallIntegerTagsIn(ClassReg); gMoveRR(ClassReg, ReceiverResultReg); - gRetN(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, gLabel())); return 0; } @@ -9335,8 +8885,8 @@ AbstractInstruction *jumpOverflow; AbstractInstruction *jumpZero; - gMoveRR(Arg0Reg, TempReg); - gMoveRR(Arg0Reg, ClassReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gMoveRR(TempReg, ClassReg); /* We must shift away the tags, not just subtract them, so that the overflow case doesn't actually overflow the machine instruction. */ @@ -9354,7 +8904,8 @@ jumpOverflow = gJumpGreaterOrEqual(0); genConvertIntegerToSmallIntegerInScratchReg(TempReg); gMoveRR(TempReg, ReceiverResultReg); - gRetN(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpOverflow, jmpTarget(jumpZero, jmpTarget(jumpNotSI, gLabel()))); return 0; } @@ -9362,30 +8913,38 @@ static sqInt genPrimitiveSize(void) { - return genInnerPrimitiveSize(0); + return genInnerPrimitiveSize(BytesPerWord); } static sqInt genPrimitiveStringAt(void) { - assert((numRegArgs()) >= 1); - return genInnerPrimitiveStringAt(0); + gMoveMwrR(BytesPerWord, SPReg, Arg0Reg); + return genInnerPrimitiveStringAt(BytesPerWord * 2); } + +/* Stack looks like + receiver (also in ResultReceiverReg) + arg + return address */ + static sqInt genPrimitiveSubtract(void) { AbstractInstruction *jumpNotSI; AbstractInstruction *jumpOvfl; - gMoveRR(Arg0Reg, TempReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gMoveRR(TempReg, ClassReg); jumpNotSI = genJumpNotSmallIntegerInScratchReg(TempReg); gMoveRR(ReceiverResultReg, TempReg); - gSubRR(Arg0Reg, TempReg); + gSubRR(ClassReg, TempReg); jumpOvfl = gJumpOverflow(0); genAddSmallIntegerTagsTo(TempReg); gMoveRR(TempReg, ReceiverResultReg); - gRetN(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpOvfl, jmpTarget(jumpNotSI, gLabel())); return 0; } @@ -9459,10 +9018,9 @@ genPushActiveContextBytecode(void) { assert(needsFrame); - (optStatus.isReceiverResultRegLive = 0); - ssAllocateCallReg(ReceiverResultReg); CallRT(cePushActiveContextTrampoline); - return ssPushRegister(ReceiverResultReg); + gPushR(ReceiverResultReg); + return 0; } @@ -9496,18 +9054,18 @@ assert(needsFrame); addBlockStartAtnumArgsnumCopiedspan(bytecodePointer + 4, byte1 & 15, numCopied = ((usqInt) byte1) >> 4, (byte2 << 8) + byte3); - if (numCopied > 0) { - ssFlushTo(simStackPtr); - } - (optStatus.isReceiverResultRegLive = 0); - ssAllocateCallRegand(SendNumArgsReg, ReceiverResultReg); gMoveCqR(byte1 | ((bytecodePointer + 5) << 8), SendNumArgsReg); CallRT(ceClosureCopyTrampoline); if (numCopied > 0) { - gAddCqR(numCopied * BytesPerWord, SPReg); - ssPop(numCopied); + if (numCopied > 1) { + gAddCqR((numCopied - 1) * BytesPerWord, SPReg); + } + gMoveRMwr(ReceiverResultReg, 0, SPReg); } - return ssPushRegister(ReceiverResultReg); + else { + gPushR(ReceiverResultReg); + } + return 0; } static sqInt @@ -9556,25 +9114,22 @@ genPushLiteralVariable(sqInt literalIndex) { sqInt association; - sqInt freeReg; - freeReg = ssAllocatePreferredReg(ClassReg); /* 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-or-evaluation issue if we defer the dereference. */ association = literalofMethod(literalIndex, methodObj); - annotateobjRef(gMoveCwR(association, TempReg), association); - genLoadSlotsourceRegdestReg(ValueIndex, TempReg, freeReg); - ssPushRegister(freeReg); + annotateobjRef(gMoveCwR(association, ClassReg), association); + genLoadSlotsourceRegdestReg(ValueIndex, ClassReg, TempReg); + gPushR(TempReg); return 0; } static sqInt genPushLiteral(sqInt literal) { - return ssPushConstant(literal); + annotateobjRef(gPushCw(literal), literal); + return 0; } static sqInt @@ -9584,16 +9139,14 @@ AbstractInstruction *jmpSingle; assert(needsFrame); - ssAllocateCallRegand(ReceiverResultReg, SendNumArgsReg); - ensureReceiverResultRegContainsSelf(); - if ((registerMaskFor(ReceiverResultReg)) & callerSavedRegMask) { - (optStatus.isReceiverResultRegLive = 0); - } if (slotIndex == InstructionPointerIndex) { + gMoveMwrR(FoxMFReceiver, FPReg, ReceiverResultReg); gMoveCqR(slotIndex, SendNumArgsReg); CallRT(ceFetchContextInstVarTrampoline); - return ssPushRegister(SendNumArgsReg); + gPushR(SendNumArgsReg); + return 0; } + gMoveMwrR(FoxMFReceiver, FPReg, ReceiverResultReg); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); jmpSingle = genJumpNotSmallIntegerInScratchReg(TempReg); gMoveCqR(slotIndex, SendNumArgsReg); @@ -9601,8 +9154,8 @@ jmpDone = gJump(0); jmpTarget(jmpSingle, gLabel()); genLoadSlotsourceRegdestReg(slotIndex, ReceiverResultReg, SendNumArgsReg); - jmpTarget(jmpDone, gLabel()); - return ssPushRegister(SendNumArgsReg); + jmpTarget(jmpDone, gPushR(SendNumArgsReg)); + return 0; } static sqInt @@ -9613,13 +9166,7 @@ sqInt size; assert(needsFrame); - (optStatus.isReceiverResultRegLive = 0); - if ((popValues = byte1 > 127)) { - ssFlushTo(simStackPtr); - } - else { - ssAllocateCallRegand(SendNumArgsReg, ReceiverResultReg); - } + popValues = byte1 > 127; size = byte1 & 127; gMoveCqR(size, SendNumArgsReg); CallRT(ceCreateNewArrayTrampoline); @@ -9628,9 +9175,9 @@ gPopR(TempReg); genStoreSourceRegslotIndexintoNewObjectInDestReg(TempReg, i, ReceiverResultReg); } - ssPop(size); } - return ssPushRegister(ReceiverResultReg); + gPushR(ReceiverResultReg); + return 0; } static sqInt @@ -9642,7 +9189,14 @@ static sqInt genPushReceiverBytecode(void) { - return ssPushDesc(simSelf); + if (needsFrame) { + gMoveMwrR(FoxMFReceiver, FPReg, TempReg); + gPushR(TempReg); + } + else { + gPushR(ReceiverResultReg); + } + return 0; } static sqInt @@ -9654,113 +9208,26 @@ static sqInt genPushReceiverVariable(sqInt index) { - ensureReceiverResultRegContainsSelf(); - return genSSPushSlotreg(index, ReceiverResultReg); -} + sqInt maybeErr; - -/* Ensure that the register args are pushed before the retpc for methods with - arity <= self numRegArgs. - */ -/* This won't be 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. */ - -static void -genPushRegisterArgs(void) -{ - if (!(regArgsHaveBeenPushed - || (methodOrBlockNumArgs > (numRegArgs())))) { - genPushRegisterArgsForNumArgs(methodOrBlockNumArgs); - regArgsHaveBeenPushed = 1; + if (needsFrame) { + gMoveMwrR(FoxMFReceiver, FPReg, ReceiverResultReg); } -} - - -/* 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. */ -/* This won't be 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. */ -/* Iff there are register args convert - base -> outerRetpc (send site retpc) - sp -> innerRetpc (PIC abort/miss retpc) - to - base -> receiver - (arg0) - (arg1) - outerRetpc - sp -> innerRetpc (PIC abort/miss retpc) */ - -static void -genPushRegisterArgsForAbortMissNumArgs(sqInt numArgs) -{ - if (numArgs <= (numRegArgs())) { - assert((numRegArgs()) <= 2); - if (numArgs == 0) { - gMoveMwrR(0, SPReg, TempReg); - gPushR(TempReg); - gMoveMwrR(BytesPerWord * 2, SPReg, TempReg); - gMoveRMwr(TempReg, BytesPerWord, SPReg); - gMoveRMwr(ReceiverResultReg, 2 * BytesPerWord, SPReg); - return; - } - if (numArgs == 1) { - gMoveMwrR(BytesPerWord, SPReg, TempReg); - gPushR(TempReg); - gMoveMwrR(BytesPerWord, SPReg, TempReg); - gPushR(TempReg); - gMoveRMwr(ReceiverResultReg, 3 * BytesPerWord, SPReg); - gMoveRMwr(Arg0Reg, 2 * BytesPerWord, SPReg); - return; - } - if (numArgs == 2) { - gPushR(Arg1Reg); - gMoveMwrR(BytesPerWord * 2, SPReg, TempReg); - gPushR(TempReg); - gMoveMwrR(BytesPerWord * 2, SPReg, TempReg); - gPushR(TempReg); - gMoveRMwr(ReceiverResultReg, 4 * BytesPerWord, SPReg); - gMoveRMwr(Arg0Reg, 3 * BytesPerWord, SPReg); - return; - } + maybeErr = genLoadSlotsourceRegdestReg(index, ReceiverResultReg, TempReg); + if (maybeErr < 0) { + return maybeErr; } + gPushR(TempReg); + return 0; } - -/* Ensure that the register args are pushed before the retpc for arity <= - self numRegArgs. - */ -/* This won't be 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. */ - -static void -genPushRegisterArgsForNumArgs(sqInt numArgs) -{ - if (numArgs <= (numRegArgs())) { - gMoveMwrR(0, SPReg, TempReg); - gMoveRMwr(ReceiverResultReg, 0, SPReg); - assert((numRegArgs()) <= 2); - if (numArgs > 0) { - gPushR(Arg0Reg); - if (numArgs > 1) { - gPushR(Arg1Reg); - } - } - gPushR(TempReg); - } -} - static sqInt genPushRemoteTempLongBytecode(void) { - ssAllocateRequiredRegand(ClassReg, SendNumArgsReg); gMoveMwrR(frameOffsetOfTemporary(byte2), FPReg, ClassReg); - genLoadSlotsourceRegdestReg(byte1, ClassReg, SendNumArgsReg); - return ssPushRegister(SendNumArgsReg); + genLoadSlotsourceRegdestReg(byte1, ClassReg, TempReg); + gPushR(TempReg); + return 0; } static sqInt @@ -9772,7 +9239,9 @@ static sqInt genPushTemporaryVariable(sqInt index) { - return ssPushDesc(simStack[index]); + gMoveMwrR(frameOffsetOfTemporary(index), FPReg, TempReg); + gPushR(TempReg); + return 0; } @@ -9919,8 +9388,8 @@ genReturnTopFromBlock(void) { assert(inBlock); - popToReg(ssTop(), ReceiverResultReg); - ssPop(1); + flag("currently caller pushes result"); + gPopR(ReceiverResultReg); if (needsFrame) { gMoveRR(FPReg, SPReg); gPopR(FPReg); @@ -9929,11 +9398,16 @@ return 0; } + +/* Return pops receiver and arguments off the stack. Callee pushes the + result. + */ + static sqInt genReturnTopFromMethod(void) { - popToReg(ssTop(), ReceiverResultReg); - ssPop(1); + flag("currently caller pushes result"); + gPopR(ReceiverResultReg); return genUpArrowReturn(); } @@ -10016,32 +9490,37 @@ static sqInt genSendSupernumArgs(sqInt selector, sqInt numArgs) { - marshallSendArguments(numArgs); - return genMarshalledSendSupernumArgs(selector, numArgs); + assert(needsFrame); + if (isYoung(selector)) { + hasYoungReferent = 1; + } + gMoveMwrR(numArgs * BytesPerWord, SPReg, ReceiverResultReg); + if (numArgs > 2) { + gMoveCqR(numArgs, SendNumArgsReg); + } + gMoveCwR(selector, ClassReg); + CallSend(superSendTrampolines[((numArgs < (NumSendTrampolines - 1)) ? numArgs : (NumSendTrampolines - 1))]); + flag("currently caller pushes result"); + gPushR(ReceiverResultReg); + return 0; } - -/* Generate a trampoline with four arguments. - Hack: a negative value indicates an abstract register, a non-negative - value indicates a constant. */ - static sqInt -genSendTrampolineFornumArgscalledargargargarg(void *aRoutine, sqInt numArgs, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3) -{ - sqInt startAddress; - - startAddress = methodZoneBase; - opcodeIndex = 0; - genPushRegisterArgsForNumArgs(numArgs); - genTrampolineForcalledcallJumpBarnumArgsargargargargsaveRegsresultRegappendOpcodes(aRoutine, aString, 1, 4, regOrConst0, regOrConst1, regOrConst2, regOrConst3, 0, null, 1); - return startAddress; -} - -static sqInt genSendnumArgs(sqInt selector, sqInt numArgs) { - marshallSendArguments(numArgs); - return genMarshalledSendnumArgs(selector, numArgs); + if (isYoung(selector)) { + hasYoungReferent = 1; + } + assert(needsFrame); + gMoveMwrR(numArgs * BytesPerWord, SPReg, ReceiverResultReg); + if (numArgs > 2) { + gMoveCqR(numArgs, SendNumArgsReg); + } + gMoveCwR(selector, ClassReg); + CallSend(sendTrampolines[((numArgs < (NumSendTrampolines - 1)) ? numArgs : (NumSendTrampolines - 1))]); + flag("currently caller pushes result"); + gPushR(ReceiverResultReg); + return 0; } static sqInt @@ -10073,376 +9552,55 @@ return genJumpTo(target); } + +/* Stack looks like + receiver (also in ResultReceiverReg) + arg + return address */ + static sqInt genSmallIntegerComparison(sqInt jumpOpcode) { AbstractInstruction *jumpFail; AbstractInstruction *jumpTrue; - gMoveRR(Arg0Reg, TempReg); + gMoveMwrR(BytesPerWord, SPReg, TempReg); + gMoveRR(TempReg, ClassReg); jumpFail = genJumpNotSmallIntegerInScratchReg(TempReg); - gCmpRR(Arg0Reg, ReceiverResultReg); + gCmpRR(ClassReg, ReceiverResultReg); jumpTrue = gen(jumpOpcode); annotateobjRef(gMoveCwR(falseObject(), ReceiverResultReg), falseObject()); - gRetN(0); + flag("currently caller pushes result"); + gRetN(BytesPerWord * 2); jmpTarget(jumpTrue, annotateobjRef(gMoveCwR(trueObject(), ReceiverResultReg), trueObject())); - gRetN(0); + gRetN(BytesPerWord * 2); jmpTarget(jumpFail, gLabel()); return 0; } static sqInt -genSpecialSelectorArithmetic(void) -{ - sqInt argInt; - sqInt argIsInt; - AbstractInstruction *jumpContinue; - AbstractInstruction *jumpNotSmallInts; - BytecodeDescriptor *primDescriptor; - sqInt rcvrInt; - sqInt rcvrIsInt; - sqInt result; - - primDescriptor = generatorAt(byte0); - argIsInt = (((ssTop()->type)) == SSConstant) - && ((((argInt = (ssTop()->constant))) & 1)); - rcvrIsInt = (((ssValue(1)->type)) == SSConstant) - && ((((rcvrInt = (ssValue(1)->constant))) & 1)); - if (argIsInt - && (rcvrIsInt)) { - 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)) { - annotateBytecode(gLabel()); - return ssPop(2),ssPushConstant(((result << 1) | 1)); - } - return genSpecialSelectorSend(); - } - if (!(argIsInt - || (rcvrIsInt))) { - return genSpecialSelectorSend(); - } - if (argIsInt) { - ssFlushTo(simStackPtr - 2); - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - gMoveRR(ReceiverResultReg, TempReg); - } - else { - marshallSendArguments(1); - gMoveRR(Arg0Reg, TempReg); - if (!(rcvrIsInt)) { - if (isSmallIntegerTagNonZero()) { - gAndRR(ReceiverResultReg, TempReg); - } - else { - gOrRR(ReceiverResultReg, TempReg); - } - } - } - jumpNotSmallInts = genJumpNotSmallIntegerInScratchReg(TempReg); - - switch ((primDescriptor->opcode)) { - case AddRR: - if (argIsInt) { - gAddCqR(argInt - ConstZero, ReceiverResultReg); - - /* overflow; must undo the damage before continuing */ - - jumpContinue = gJumpNoOverflow(0); - gSubCqR(argInt - ConstZero, ReceiverResultReg); - } - else { - genRemoveSmallIntegerTagsInScratchReg(ReceiverResultReg); - gAddRR(Arg0Reg, ReceiverResultReg); - - /* overflow; must undo the damage before continuing */ - - jumpContinue = gJumpNoOverflow(0); - if (rcvrIsInt) { - gMoveCqR(rcvrInt, ReceiverResultReg); - } - else { - gSubRR(Arg0Reg, ReceiverResultReg); - genSetSmallIntegerTagsIn(ReceiverResultReg); - } - } - break; - case SubRR: - if (argIsInt) { - gSubCqR(argInt - ConstZero, ReceiverResultReg); - - /* overflow; must undo the damage before continuing */ - - jumpContinue = gJumpNoOverflow(0); - gAddCqR(argInt - ConstZero, ReceiverResultReg); - } - else { - genRemoveSmallIntegerTagsInScratchReg(Arg0Reg); - gSubRR(Arg0Reg, ReceiverResultReg); - - /* overflow; must undo the damage before continuing */ - - jumpContinue = gJumpNoOverflow(0); - gAddRR(Arg0Reg, ReceiverResultReg); - genSetSmallIntegerTagsIn(Arg0Reg); - } - break; - case AndRR: - if (argIsInt) { - gAndCqR(argInt, ReceiverResultReg); - } - else { - gAndRR(Arg0Reg, ReceiverResultReg); - } - jumpContinue = gJump(0); - break; - case OrRR: - if (argIsInt) { - gOrCqR(argInt, ReceiverResultReg); - } - else { - gOrRR(Arg0Reg, ReceiverResultReg); - } - jumpContinue = gJump(0); - break; - default: - error("Case not found and no otherwise clause"); - } - jmpTarget(jumpNotSmallInts, gLabel()); - if (argIsInt) { - gMoveCqR(argInt, Arg0Reg); - } - genMarshalledSendnumArgs(specialSelector(byte0 - 176), 1); - jmpTarget(jumpContinue, gLabel()); - return 0; -} - -static sqInt genSpecialSelectorClass(void) { - ssPop(1); - ssAllocateRequiredRegand(SendNumArgsReg, ClassReg); - ssPush(1); - popToReg(ssTop(), SendNumArgsReg); + gMoveMwrR(0, SPReg, SendNumArgsReg); genGetClassObjectOfintoscratchReg(SendNumArgsReg, ClassReg, TempReg); - return ssPop(1),ssPushRegister(ClassReg); + gMoveRMwr(ClassReg, 0, SPReg); + return 0; } static sqInt -genSpecialSelectorComparison(void) -{ - sqInt argInt; - sqInt argIsInt; - sqInt branchBytecode; - BytecodeDescriptor *branchDescriptor; - sqInt branchPC; - sqInt inlineCAB; - AbstractInstruction *jumpNotSmallInts; - sqInt postBranchPC; - BytecodeDescriptor *primDescriptor; - sqInt rcvrInt; - sqInt rcvrIsInt; - sqInt result; - sqInt targetBytecodePC; - - ssFlushTo(simStackPtr - 2); - primDescriptor = generatorAt(byte0); - argIsInt = (((ssTop()->type)) == SSConstant) - && ((((argInt = (ssTop()->constant))) & 1)); - rcvrIsInt = (((ssValue(1)->type)) == SSConstant) - && ((((rcvrInt = (ssValue(1)->constant))) & 1)); - if (argIsInt - && (rcvrIsInt)) { - ; - - 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"); - } - annotateBytecode(gLabel()); - ssPop(2); - return ssPushConstant((result - ? trueObject() - : falseObject())); - } - branchPC = bytecodePointer + ((primDescriptor->numBytes)); - branchBytecode = fetchByteofObject(branchPC, methodObj); - - /* Only interested in inlining if followed by a conditional branch. */ - - branchDescriptor = generatorAt(branchBytecode); - - /* Further, only interested in inlining = and ~= if there's a SmallInteger constant involved. - The relational operators successfully staticaly predict SmallIntegers; the equality operators do not. */ - - inlineCAB = ((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse)); - if (inlineCAB - && ((((primDescriptor->opcode)) == JumpZero) - || (((primDescriptor->opcode)) == JumpNonZero))) { - inlineCAB = argIsInt - || (rcvrIsInt); - } - if (!(inlineCAB)) { - return genSpecialSelectorSend(); - } - targetBytecodePC = (branchPC + ((branchDescriptor->numBytes))) + (spanForatbyte0in(branchDescriptor, branchPC, branchBytecode, methodObj)); - postBranchPC = branchPC + ((branchDescriptor->numBytes)); - if (argIsInt) { - ssFlushTo(simStackPtr - 2); - popToReg(ssValue(1), ReceiverResultReg); - ssPop(2); - gMoveRR(ReceiverResultReg, TempReg); - } - else { - marshallSendArguments(1); - gMoveRR(Arg0Reg, TempReg); - if (!(rcvrIsInt)) { - if (isSmallIntegerTagNonZero()) { - gAndRR(ReceiverResultReg, TempReg); - } - else { - gOrRR(ReceiverResultReg, TempReg); - } - } - } - jumpNotSmallInts = genJumpNotSmallIntegerInScratchReg(TempReg); - if (argIsInt) { - gCmpCqR(argInt, ReceiverResultReg); - } - else { - gCmpRR(Arg0Reg, ReceiverResultReg); - } - genoperand(((branchDescriptor->isBranchTrue) - ? (primDescriptor->opcode) - : inverseBranchFor((primDescriptor->opcode))), ((usqInt)(ensureNonMergeFixupAt(targetBytecodePC - initialPC)))); - gJump(ensureNonMergeFixupAt(postBranchPC - initialPC)); - jmpTarget(jumpNotSmallInts, gLabel()); - if (argIsInt) { - gMoveCqR(argInt, Arg0Reg); - } - return genMarshalledSendnumArgs(specialSelector(byte0 - 176), 1); -} - -static sqInt genSpecialSelectorEqualsEquals(void) { - sqInt argReg; - sqInt branchBytecode; - BytecodeDescriptor *branchDescriptor; - AbstractInstruction *jumpEqual; AbstractInstruction *jumpNotEqual; - sqInt nextPC; - sqInt postBranchPC; - BytecodeDescriptor *primDescriptor; - sqInt rcvrReg; - sqInt resultReg; - sqInt targetBytecodePC; + AbstractInstruction *jumpPush; - ssPop(2); - resultReg = availableRegisterOrNil(); - if (!(resultReg)) { - ssAllocateRequiredReg(resultReg = Arg1Reg); - } - ssPush(2); - if ((((ssTop()->type)) == SSConstant) - && (!((ssTop()->spilled)))) { - if (((ssValue(1)->type)) == SSRegister) { - - /* if spilled we must generate a real pop */ - - rcvrReg = (ssValue(1)->registerr); - } - else { - popToReg(ssValue(1), rcvrReg = resultReg); - } - if (shouldAnnotateObjectReference((ssTop()->constant))) { - annotateobjRef(gCmpCwR((ssTop()->constant), rcvrReg), (ssTop()->constant)); - } - else { - gCmpCqR((ssTop()->constant), rcvrReg); - } - ssPop(1); - } - else { - argReg = ssStorePoptoPreferredReg(1, TempReg); - rcvrReg = (argReg == resultReg - ? TempReg - : resultReg); - popToReg(ssTop(), rcvrReg); - gCmpRR(argReg, rcvrReg); - } - ssPop(1); - ssPushRegister(resultReg); - primDescriptor = generatorAt(byte0); - nextPC = bytecodePointer + ((primDescriptor->numBytes)); - branchBytecode = fetchByteofObject(nextPC, methodObj); - branchDescriptor = generatorAt(branchBytecode); - if (((branchDescriptor->isBranchTrue)) - || ((branchDescriptor->isBranchFalse))) { - ssFlushTo(simStackPtr - 1); - targetBytecodePC = (nextPC + ((branchDescriptor->numBytes))) + (spanForatbyte0in(branchDescriptor, nextPC, branchBytecode, methodObj)); - postBranchPC = nextPC + ((branchDescriptor->numBytes)); - if (((fixupAt(nextPC - initialPC)->targetInstruction)) == 0) { - - /* The next instruction is dead. we can skip it. */ - - deadCode = 1; - ssPop(1); - ensureFixupAt(targetBytecodePC - initialPC); - ensureFixupAt(postBranchPC - initialPC); - } - genoperand(((branchDescriptor->isBranchTrue) - ? JumpZero - : JumpNonZero), ((usqInt)(ensureNonMergeFixupAt(targetBytecodePC - initialPC)))); - gJump(ensureNonMergeFixupAt(postBranchPC - initialPC)); - } - else { - jumpNotEqual = gJumpNonZero(0); - annotateobjRef(gMoveCwR(trueObject(), resultReg), trueObject()); - jumpEqual = gJump(0); - jmpTarget(jumpNotEqual, annotateobjRef(gMoveCwR(falseObject(), resultReg), falseObject())); - jmpTarget(jumpEqual, gLabel()); - } - if (resultReg == ReceiverResultReg) { - (optStatus.isReceiverResultRegLive = 0); - } + gPopR(TempReg); + gMoveMwrR(0, SPReg, ClassReg); + gCmpRR(TempReg, ClassReg); + jumpNotEqual = gJumpNonZero(0); + annotateobjRef(gMoveCwR(trueObject(), TempReg), trueObject()); + jumpPush = gJump(0); + jmpTarget(jumpNotEqual, annotateobjRef(gMoveCwR(falseObject(), TempReg), falseObject())); + jmpTarget(jumpPush, gMoveRMwr(TempReg, 0, SPReg)); return 0; } @@ -10460,12 +9618,6 @@ } static sqInt -genSSPushSlotreg(sqInt index, sqInt baseReg) -{ - return ssPushBaseoffset(baseReg, slotOffsetOfInstVarIndex(index)); -} - -static sqInt genStoreAndPopReceiverVariableBytecode(void) { return genStorePopReceiverVariable(1, byte0 & 7); @@ -10493,57 +9645,23 @@ } static sqInt -genStoreImmediateInSourceRegslotIndexdestReg(sqInt sourceReg, sqInt index, sqInt destReg) -{ - gMoveRMwr(sourceReg, (index * BytesPerWord) + BaseHeaderSize, destReg); - return 0; -} - -static sqInt genStorePopLiteralVariable(sqInt popBoolean, sqInt litVarIndex) { sqInt association; - sqInt constVal; - sqInt topReg; - sqInt valueReg; - flag("with better register allocation this wouldn't need a frame. e.g. use SendNumArgs instead of ReceiverResultReg"); assert(needsFrame); association = literalofMethod(litVarIndex, methodObj); - (optStatus.isReceiverResultRegLive = 0); - if ((((ssTop()->type)) == SSConstant) - && (isImmediate((ssTop()->constant)))) { - constVal = (ssTop()->constant); - if (popBoolean) { - ssPop(1); - } - ssAllocateRequiredReg(ReceiverResultReg); - annotateobjRef(gMoveCwR(association, ReceiverResultReg), association); - gMoveCqR(constVal, TempReg); - if (traceStores > 0) { - CallRT(ceTraceStoreTrampoline); - } - return genStoreImmediateInSourceRegslotIndexdestReg(TempReg, ValueIndex, ReceiverResultReg); + annotateobjRef(gMoveCwR(association, ReceiverResultReg), association); + if (popBoolean) { + gPopR(ClassReg); } - if ((((topReg = registerOrNil(ssTop()))) == null) - || (topReg == ReceiverResultReg)) { - topReg = ClassReg; + else { + gMoveMwrR(0, SPReg, ClassReg); } - ssPop(1); - ssAllocateRequiredReg(topReg); - ssPush(1); - flag("but what if we don't pop? The top reg is still potentially trashed in the call;. think this through"); - valueReg = ssStorePoptoPreferredReg(popBoolean, topReg); - if (valueReg == ReceiverResultReg) { - gMoveRR(valueReg, topReg); - } - ssAllocateCallReg(ReceiverResultReg); - annotateobjRef(gMoveCwR(association, ReceiverResultReg), association); if (traceStores > 0) { - gMoveRR(topReg, TempReg); CallRT(ceTraceStoreTrampoline); } - return genStoreSourceRegslotIndexdestRegscratchReg(topReg, ValueIndex, ReceiverResultReg, TempReg); + return genStoreSourceRegslotIndexdestRegscratchReg(ClassReg, ValueIndex, ReceiverResultReg, TempReg); } static sqInt @@ -10553,28 +9671,21 @@ AbstractInstruction *jmpSingle; assert(needsFrame); - ssFlushUpThroughReceiverVariable(slotIndex); - ensureReceiverResultRegContainsSelf(); - ssPop(1); - ssAllocateCallRegand(ClassReg, SendNumArgsReg); - ssPush(1); + gMoveMwrR(FoxMFReceiver, FPReg, ReceiverResultReg); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); - flag("why do we always pop??"); - flag("but what if we don't pop? The top reg is still potentially trashed in the call;. think this through"); - popToReg(ssTop(), ClassReg); + gMoveMwrR(0, SPReg, ClassReg); jmpSingle = genJumpNotSmallIntegerInScratchReg(TempReg); gMoveCqR(slotIndex, SendNumArgsReg); CallRT(ceStoreContextInstVarTrampoline); jmpDone = gJump(0); jmpTarget(jmpSingle, gLabel()); if (traceStores > 0) { - gMoveRR(ClassReg, TempReg); CallRT(ceTraceStoreTrampoline); } genStoreSourceRegslotIndexdestRegscratchReg(ClassReg, slotIndex, ReceiverResultReg, TempReg); jmpTarget(jmpDone, gLabel()); if (popBoolean) { - ssPop(1); + gAddCqR(BytesPerWord, SPReg); } return 0; } @@ -10582,100 +9693,48 @@ static sqInt genStorePopReceiverVariable(sqInt popBoolean, sqInt slotIndex) { - sqInt constVal; - sqInt topReg; - sqInt valueReg; - - ssFlushUpThroughReceiverVariable(slotIndex); - if ((((ssTop()->type)) == SSConstant) - && (isImmediate((ssTop()->constant)))) { - constVal = (ssTop()->constant); - if (popBoolean) { - ssPop(1); - } - ensureReceiverResultRegContainsSelf(); - gMoveCqR(constVal, TempReg); - if (traceStores > 0) { - CallRT(ceTraceStoreTrampoline); - } - return genStoreImmediateInSourceRegslotIndexdestReg(TempReg, slotIndex, ReceiverResultReg); + if (needsFrame) { + gMoveMwrR(FoxMFReceiver, FPReg, ReceiverResultReg); } - if ((((topReg = registerOrNil(ssTop()))) == null) - || (topReg == ReceiverResultReg)) { - topReg = ClassReg; + if (popBoolean) { + gPopR(ClassReg); } - ssPop(1); - ssAllocateCallReg(topReg); - ssPush(1); - flag("but what if we don't pop? The top reg is still potentially trashed in the call;. think this through"); - valueReg = ssStorePoptoPreferredReg(popBoolean, topReg); - if (valueReg == ReceiverResultReg) { - gMoveRR(valueReg, topReg); + else { + gMoveMwrR(0, SPReg, ClassReg); } - ensureReceiverResultRegContainsSelf(); if (traceStores > 0) { - gMoveRR(topReg, TempReg); CallRT(ceTraceStoreTrampoline); } - return genStoreSourceRegslotIndexdestRegscratchReg(topReg, slotIndex, ReceiverResultReg, TempReg); + return genStoreSourceRegslotIndexdestRegscratchReg(ClassReg, slotIndex, ReceiverResultReg, TempReg); } static sqInt genStorePopRemoteTempAt(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex) { - sqInt constVal; - sqInt topReg; - sqInt valueReg; - assert(needsFrame); - (optStatus.isReceiverResultRegLive = 0); - if ((((ssTop()->type)) == SSConstant) - && (isImmediate((ssTop()->constant)))) { - constVal = (ssTop()->constant); - if (popBoolean) { - ssPop(1); - } - ssAllocateRequiredReg(ReceiverResultReg); - gMoveMwrR(frameOffsetOfTemporary(remoteTempIndex), FPReg, ReceiverResultReg); - gMoveCqR(constVal, TempReg); - if (traceStores > 0) { - CallRT(ceTraceStoreTrampoline); - } - return genStoreImmediateInSourceRegslotIndexdestReg(TempReg, slotIndex, ReceiverResultReg); + if (popBoolean) { + gPopR(ClassReg); } - if ((((topReg = registerOrNil(ssTop()))) == null) - || (topReg == ReceiverResultReg)) { - topReg = ClassReg; + else { + gMoveMwrR(0, SPReg, ClassReg); } - ssPop(1); - ssAllocateRequiredReg(topReg); - ssPush(1); - flag("but what if we don't pop? The top reg is still potentially trashed in the call;. think this through"); - valueReg = ssStorePoptoPreferredReg(popBoolean, topReg); - if (valueReg == ReceiverResultReg) { - gMoveRR(valueReg, topReg); - } - if (!(popBoolean)) { - ssPop(1); - ssPushRegister(topReg); - } - ssAllocateCallReg(ReceiverResultReg); gMoveMwrR(frameOffsetOfTemporary(remoteTempIndex), FPReg, ReceiverResultReg); if (traceStores > 0) { - gMoveRR(topReg, TempReg); CallRT(ceTraceStoreTrampoline); } - return genStoreSourceRegslotIndexdestRegscratchReg(topReg, slotIndex, ReceiverResultReg, TempReg); + return genStoreSourceRegslotIndexdestRegscratchReg(ClassReg, slotIndex, ReceiverResultReg, TempReg); } static sqInt genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex) { - sqInt reg; - - ssFlushUpThroughTemporaryVariable(tempIndex); - reg = ssStorePoptoPreferredReg(popBoolean, TempReg); - gMoveRMwr(reg, frameOffsetOfTemporary(tempIndex), FPReg); + if (popBoolean) { + gPopR(TempReg); + } + else { + gMoveMwrR(0, SPReg, TempReg); + } + gMoveRMwr(TempReg, frameOffsetOfTemporary(tempIndex), FPReg); return 0; } @@ -10768,6 +9827,28 @@ } +/* Generate a trampoline with two arguments. + Hack: a negative value indicates an abstract register, a non-negative + value indicates a constant. */ + +static sqInt +genTrampolineForcalledargarg(void *aRoutine, char *aString, sqInt regOrConst0, sqInt regOrConst1) +{ + return genTrampolineForcalledcallJumpBarnumArgsargargargargsaveRegsresultRegappendOpcodes(aRoutine, aString, 1, 2, regOrConst0, regOrConst1, null, null, 0, null, 0); +} + + +/* Generate a trampoline with four arguments. + Hack: a negative value indicates an abstract register, a non-negative + value indicates a constant. */ + +static sqInt +genTrampolineForcalledargargargarg(void *aRoutine, char *aString, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3) +{ + return genTrampolineForcalledcallJumpBarnumArgsargargargargsaveRegsresultRegappendOpcodes(aRoutine, aString, 1, 4, regOrConst0, regOrConst1, regOrConst2, regOrConst3, 0, null, 0); +} + + /* Generate a trampoline with two arguments that answers a result. Hack: a negative value indicates an abstract register, a non-negative value indicates a constant. */ @@ -10837,6 +9918,7 @@ static sqInt genUpArrowReturn(void) { + flag("currently caller pushes result"); if (inBlock) { assert(needsFrame); annotateBytecode(CallRT(ceNonLocalReturnTrampoline)); @@ -10845,14 +9927,8 @@ if (needsFrame) { gMoveRR(FPReg, SPReg); gPopR(FPReg); - gRetN((methodOrBlockNumArgs + 1) * BytesPerWord); } - else { - gRetN(((methodOrBlockNumArgs > (numRegArgs())) - || (regArgsHaveBeenPushed) - ? (methodOrBlockNumArgs + 1) * BytesPerWord - : 0)); - } + gRetN((methodOrBlockNumArgs + 1) * BytesPerWord); return 0; } @@ -11078,7 +10154,6 @@ (methodLabel->opcode = Label); ((methodLabel->operands))[0] = 0; ((methodLabel->operands))[1] = 0; - callerSavedRegMask = callerSavedRegisterMask(backEnd); } void @@ -11103,9 +10178,6 @@ /* Make sure there's a flagged fixup at the targetIndex (pc relative to first pc) in fixups. - These are the targets of backward branches. A backward branch fixup's - simStackPtr needs to be set when generating the code for the bytecode at - the targetIndex. Initially a fixup's target is just a flag. Later on it is replaced with a proper instruction. */ @@ -11115,8 +10187,7 @@ BytecodeFixup *fixup; fixup = fixupAt(targetIndex); - (fixup->targetInstruction = ((AbstractInstruction *) 2)); - (fixup->simStackPtr = -2); + (fixup->targetInstruction = ((AbstractInstruction *) 1)); return fixup; } @@ -11147,73 +10218,7 @@ return 3; } -static void -initSimStackForFramefulMethod(sqInt startpc) -{ - CogSimStackEntry *desc; - sqInt i; - (optStatus.isReceiverResultRegLive = 0); - (simSelf.type = SSBaseOffset); - (simSelf.registerr = FPReg); - (simSelf.offset = FoxMFReceiver); - (simSelf.spilled = 1); - - /* N.B. Includes num args */ - - simSpillBase = methodOrBlockNumTemps; - - /* args */ - - simStackPtr = simSpillBase - 1; - for (i = 0; i <= (methodOrBlockNumArgs - 1); i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->registerr = FPReg); - (desc->offset = FoxCallerSavedIP + ((methodOrBlockNumArgs - i) * BytesPerWord)); - (desc->spilled = 1); - (desc->bcptr = startpc); - } - for (i = methodOrBlockNumArgs; i <= simStackPtr; i += 1) { - desc = simStackAt(i); - (desc->type = SSBaseOffset); - (desc->registerr = FPReg); - (desc->offset = FoxMFReceiver - (((i - methodOrBlockNumArgs) + 1) * BytesPerWord)); - (desc->spilled = 1); - (desc->bcptr = startpc); - } -} - -static void -initSimStackForFramelessMethod(sqInt startpc) -{ - CogSimStackEntry *desc; - - (simSelf.type = SSRegister); - (simSelf.registerr = ReceiverResultReg); - (simSelf.spilled = 0); - (optStatus.isReceiverResultRegLive = 1); - (optStatus.ssEntry = (&simSelf)); - assert(methodOrBlockNumTemps == methodOrBlockNumArgs); - simStackPtr = simSpillBase = -1; - assert((numRegArgs()) <= 2); - if (((methodOrBlockNumArgs >= 1) && (methodOrBlockNumArgs <= (numRegArgs())))) { - desc = simStackAt(0); - (desc->type = SSRegister); - (desc->registerr = Arg0Reg); - (desc->spilled = 0); - (desc->bcptr = startpc); - if (methodOrBlockNumArgs > 1) { - desc = simStackAt(1); - (desc->type = SSRegister); - (desc->registerr = Arg1Reg); - (desc->spilled = 0); - (desc->bcptr = startpc); - } - } -} - - /* Answer the inline cache tag for the return address of a send. */ static sqInt @@ -11306,72 +10311,6 @@ } static sqInt -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; -} - -static sqInt isAFixup(AbstractInstruction * self_in_isAFixup, void *fixupOrAddress) { return addressIsInFixups(fixupOrAddress); @@ -11457,12 +10396,6 @@ || (((target >= methodZoneBase) && (target <= (zoneLimit())))); } -static sqInt -isSmallIntegerTagNonZero(void) -{ - return 1; -} - static AbstractInstruction * gJumpAboveOrEqual(void *jumpTarget) { @@ -11570,12 +10503,6 @@ } static AbstractInstruction * -gJumpNoOverflow(void *jumpTarget) -{ - return genoperand(JumpNoOverflow, ((sqInt)jumpTarget)); -} - -static AbstractInstruction * gJumpOverflow(void *jumpTarget) { return genoperand(JumpOverflow, ((sqInt)jumpTarget)); @@ -11801,20 +10728,7 @@ return ((((byteAt(followingAddress - 1)) << 24) + ((byteAt(followingAddress - 2)) << 16)) + ((byteAt(followingAddress - 3)) << 8)) + (byteAt(followingAddress - 4)); } -static sqInt -liveRegisters(void) -{ - sqInt i; - sqInt regsSet; - regsSet = 0; - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= simStackPtr; i += 1) { - regsSet = regsSet | (registerMask(simStackAt(i))); - } - return regsSet; -} - - /* Answer the byte size of a MoveCwR opcode's corresponding machine code */ static sqInt @@ -12516,45 +11430,6 @@ 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. */ - -static void -marshallSendArguments(sqInt numArgs) -{ - if (numArgs > (numRegArgs())) { - ssFlushTo(simStackPtr); - storeToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg); - } - else { - ssFlushTo((simStackPtr - numArgs) - 1); - if (numArgs > 0) { - if (((numRegArgs()) > 1) - && (numArgs > 1)) { - ssAllocateRequiredRegupThrough(Arg0Reg, simStackPtr - 2); - ssAllocateRequiredRegupThrough(Arg1Reg, simStackPtr - 1); - } - else { - ssAllocateRequiredRegupThrough(Arg0Reg, simStackPtr - 1); - } - } - if (((numRegArgs()) > 1) - && (numArgs > 1)) { - popToReg(simStackAt(simStackPtr), Arg1Reg); - } - if (numArgs > 0) { - popToReg(simStackAt((simStackPtr - numArgs) + 1), Arg0Reg); - } - popToReg(simStackAt(simStackPtr - numArgs), ReceiverResultReg); - } - ssPop(numArgs + 1); -} - usqInt maxCogMethodAddress(void) { @@ -12634,64 +11509,10 @@ : absPC); } - -/* Discard type information because of a control-flow merge. */ - -static void -mergeAtfrom(CogSimStackEntry * self_in_mergeAtfrom, sqInt baseOffset, sqInt baseRegister) -{ - assert((self_in_mergeAtfrom->spilled)); - if (((self_in_mergeAtfrom->type)) == SSSpill) { - assert((((self_in_mergeAtfrom->offset)) == baseOffset) - && (((self_in_mergeAtfrom->registerr)) == baseRegister)); - } - else { - (self_in_mergeAtfrom->type) = SSSpill; - (self_in_mergeAtfrom->offset) = baseOffset; - (self_in_mergeAtfrom->registerr) = baseRegister; - } -} - - -/* Merge control flow at a fixup. The fixup holds the simStackPtr at the jump - to this target. - See stackToRegisterMapping on the class side for a full description. */ - -static void -mergeafterReturn(BytecodeFixup *fixup, sqInt mergeFollowsReturn) -{ - sqInt i; - - traceMerge(fixup); - (optStatus.isReceiverResultRegLive = 0); - if (mergeFollowsReturn) { - assert((((usqInt)((fixup->targetInstruction)))) >= 2); - simStackPtr = (fixup->simStackPtr); - } - if ((((usqInt)((fixup->targetInstruction)))) <= 2) { - ssFlushTo(simStackPtr); - if (((fixup->simStackPtr)) <= -2) { - (fixup->simStackPtr = simStackPtr); - } - (fixup->targetInstruction = gLabel()); - } - assert(simStackPtr >= ((fixup->simStackPtr))); - ; - simStackPtr = (fixup->simStackPtr); - - /* For now throw away all type information for values on the stack, but sometime consider - the more sophisticated merge described in the class side stackToRegisterMapping. */ - - simSpillBase = methodOrBlockNumTemps; - for (i = methodOrBlockNumTemps; i <= simStackPtr; i += 1) { - mergeAtfrom(simStackAt(i), FoxMFReceiver - (((i - methodOrBlockNumArgs) + 1) * BytesPerOop), FPReg); - } -} - static sqInt methodAbortTrampolineFor(sqInt numArgs) { - return methodAbortTrampolines[((numArgs < ((numRegArgs()) + 1)) ? numArgs : ((numRegArgs()) + 1))]; + return ceMethodAbortTrampoline; } static CogMethod * @@ -12746,13 +11567,7 @@ return genoperand(NegateR, reg); } -static AbstractInstruction * -gNop(void) -{ - return gen(Nop); -} - /* Compute the distance to the logically subsequent bytecode, i.e. skip over blocks. */ @@ -13079,7 +11894,7 @@ static sqInt picAbortTrampolineFor(sqInt numArgs) { - return picAbortTrampolines[((numArgs < ((numRegArgs()) + 1)) ? numArgs : ((numRegArgs()) + 1))]; + return cePICAbortTrampoline; } @@ -13107,37 +11922,7 @@ } } -static void -popToReg(CogSimStackEntry * self_in_popToReg, sqInt reg) -{ - if ((self_in_popToReg->spilled)) { - gPopR(reg); - return; - } - - switch ((self_in_popToReg->type)) { - case SSBaseOffset: - gMoveMwrR((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 { - gMoveCqR((self_in_popToReg->constant), reg); - } - break; - case SSRegister: - if (reg != ((self_in_popToReg->registerr))) { - gMoveRR((self_in_popToReg->registerr), reg); - } - break; - default: - error("Case not found and no otherwise clause"); - } -} - /* If there is a generator for the current primitive then answer it; otherwise answer nil. */ @@ -13325,45 +12110,15 @@ } -/* Answer a bit mask for the receiver's register, if any. */ +/* Dummy implementation for CogFooCompiler>callerSavedRegisterMask + which doesn't get pruned due to Slang limitations. */ static sqInt -registerMask(CogSimStackEntry * self_in_registerMask) -{ - return ((((self_in_registerMask->type)) == SSBaseOffset) - || (((self_in_registerMask->type)) == SSRegister) - ? registerMaskFor((self_in_registerMask->registerr)) - : 0); -} - - -/* Answer a bit mask identifying the symbolic register. - Registers are negative numbers. */ - -static sqInt -registerMaskFor(sqInt reg) -{ - return (((1 - reg) < 0) ? ((usqInt) 1 >> -(1 - reg)) : ((usqInt) 1 << (1 - reg))); -} - - -/* Answer a bit mask identifying the symbolic registers. - Registers are negative numbers. */ - -static sqInt registerMaskForandand(sqInt reg1, sqInt reg2, sqInt reg3) { - return (((((1 - reg1) < 0) ? ((usqInt) 1 >> -(1 - reg1)) : ((usqInt) 1 << (1 - reg1)))) | ((((1 - reg2) < 0) ? ((usqInt) 1 >> -(1 - reg2)) : ((usqInt) 1 << (1 - reg2))))) | ((((1 - reg3) < 0) ? ((usqInt) 1 >> -(1 - reg3)) : ((usqInt) 1 << (1 - reg3)))); + return 0; } -static sqInt -registerOrNil(CogSimStackEntry * self_in_registerOrNil) -{ - return (((self_in_registerOrNil->type)) == SSRegister - ? (self_in_registerOrNil->registerr) - : 0); -} - static void relocateAndPruneYoungReferrers(void) { @@ -13656,21 +12411,12 @@ } -/* We must ensure the ReceiverResultReg is live across the store check so - that we can store into receiver inst vars in a frameless method since self - exists only in ReceiverResultReg in a frameless method. So if - ReceiverResultReg is - caller-saved we use the fact that ceStoreCheck: answers its argument to - reload ReceiverResultReg cheaply. Otherwise we don't care about the result - and use the cResultRegister, effectively a no-op (see - compileTrampoline...) */ +/* See the subclass for explanation. */ static sqInt returnRegForStoreCheck(void) { - return ((registerMaskFor(ReceiverResultReg)) & callerSavedRegMask - ? ReceiverResultReg - : cResultRegister(backEnd)); + return cResultRegister(backEnd); } @@ -13816,7 +12562,6 @@ BytecodeDescriptor *descriptor; sqInt end; sqInt pc; - sqInt pushingNils; sqInt stackDelta; needsFrame = 0; @@ -13824,8 +12569,6 @@ pc = (blockStart->startpc); end = ((blockStart->startpc)) + ((blockStart->span)); stackDelta = 0; - pushingNils = 1; - (blockStart->numInitialNils = 0); while (pc < end) { byte0 = fetchByteofObject(pc, methodObj); descriptor = generatorAt(byte0); @@ -13837,20 +12580,12 @@ stackDelta += (descriptor->stackDelta); } } - if (pushingNils) { - if ((pushingNils = (((descriptor->generator)) == (genPushConstantNilBytecode)) - && (((fixupAt(pc - initialPC)->targetInstruction)) == 0))) { - assert(((descriptor->numBytes)) == 1); - (blockStart->numInitialNils = ((blockStart->numInitialNils)) + 1); - } - } pc = nextBytecodePCForatbyte0in(descriptor, pc, byte0, methodObj); } if (!(needsFrame)) { if (stackDelta < 0) { error("negative stack delta in block; block contains bogus code or internal error"); } - (blockStart->numInitialNils = 0); while (stackDelta > 0) { descriptor = generatorAt(fetchByteofObject((blockStart->startpc), methodObj)); if (((descriptor->generator)) != (genPushConstantNilBytecode)) { @@ -14173,289 +12908,7 @@ } } -static void -ssAllocateCallReg(sqInt requiredReg1) -{ - ssAllocateRequiredRegMaskupThrough(callerSavedRegMask | (registerMaskFor(requiredReg1)), simStackPtr); -} - -static void -ssAllocateCallRegand(sqInt requiredReg1, sqInt requiredReg2) -{ - ssAllocateRequiredRegMaskupThrough(callerSavedRegMask | ((registerMaskFor(requiredReg1)) | (registerMaskFor(requiredReg2))), simStackPtr); -} - static sqInt -ssAllocatePreferredReg(sqInt preferredReg) -{ - sqInt i; - sqInt lastPreferred; - sqInt liveRegs; - sqInt preferredMask; - sqInt reg; - - - /* compute live regs while noting the last occurrence of preferredReg. - If there are none free we must spill from simSpillBase to last occurrence. */ - - lastPreferred = -1; - preferredMask = registerMaskFor(preferredReg); - liveRegs = registerMaskForandand(TempReg, FPReg, SPReg); - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= simStackPtr; i += 1) { - liveRegs = liveRegs | (registerMask(simStackAt(i))); - if ((liveRegs & preferredMask) != 0) { - lastPreferred = i; - } - } - if ((liveRegs & (registerMaskFor(preferredReg))) == 0) { - return preferredReg; - } - for (reg = GPRegMin; reg <= GPRegMax; reg += 1) { - if ((liveRegs & (registerMaskFor(reg))) == 0) { - return reg; - } - } - ssFlushTo(lastPreferred); - assert(((liveRegisters()) & preferredMask) == 0); - return preferredReg; -} - -static void -ssAllocateRequiredRegMaskupThrough(sqInt requiredRegsMask, sqInt stackPtr) -{ - sqInt i; - sqInt lastRequired; - sqInt liveRegs; - - - /* 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. */ - - lastRequired = -1; - liveRegs = registerMaskForandand(TempReg, FPReg, SPReg); - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= stackPtr; i += 1) { - liveRegs = liveRegs | (registerMask(simStackAt(i))); - if ((liveRegs & requiredRegsMask) != 0) { - lastRequired = i; - } - } - if (!((liveRegs & requiredRegsMask) == 0)) { - ssFlushTo(lastRequired); - assert(((liveRegisters()) & requiredRegsMask) == 0); - } -} - -static void -ssAllocateRequiredReg(sqInt requiredReg) -{ - ssAllocateRequiredRegMaskupThrough(registerMaskFor(requiredReg), simStackPtr); -} - -static void -ssAllocateRequiredRegand(sqInt requiredReg1, sqInt requiredReg2) -{ - ssAllocateRequiredRegMaskupThrough((registerMaskFor(requiredReg1)) | (registerMaskFor(requiredReg2)), simStackPtr); -} - -static void -ssAllocateRequiredRegupThrough(sqInt requiredReg, sqInt stackPtr) -{ - ssAllocateRequiredRegMaskupThrough(registerMaskFor(requiredReg), stackPtr); -} - -static void -ssFlushTo(sqInt index) -{ - sqInt i; - - for (i = methodOrBlockNumTemps; i <= (simSpillBase - 1); i += 1) { - assert((simStackAt(i)->spilled)); - } - if (simSpillBase <= index) { - for (i = (((simSpillBase < 0) ? 0 : simSpillBase)); i <= index; i += 1) { - assert(needsFrame); - ensureSpilledAtfrom(simStackAt(i), frameOffsetOfTemporary(i), FPReg); - } - simSpillBase = index + 1; - } -} - - -/* Any occurrences on the stack of the value being stored must - be flushed, and hence any values colder than them stack. */ - -static void -ssFlushUpThroughReceiverVariable(sqInt slotIndex) -{ - CogSimStackEntry *desc; - sqInt index; - - for (index = simStackPtr; index >= (((simSpillBase < 0) ? 0 : simSpillBase)); index += -1) { - desc = simStackAt(index); - if ((((desc->type)) == SSBaseOffset) - && ((((desc->registerr)) == ReceiverResultReg) - && (((desc->offset)) == (slotOffsetOfInstVarIndex(slotIndex))))) { - ssFlushTo(index); - return; - } - } -} - - -/* Any occurrences on the stack of the value being stored must - be flushed, and hence any values colder than them stack. */ - -static void -ssFlushUpThroughTemporaryVariable(sqInt tempIndex) -{ - CogSimStackEntry *desc; - sqInt index; - - for (index = simStackPtr; index >= simSpillBase; index += -1) { - desc = simStackAt(index); - if ((((desc->type)) == SSBaseOffset) - && ((((desc->registerr)) == FPReg) - && (((desc->offset)) == (frameOffsetOfTemporary(tempIndex))))) { - ssFlushTo(index); - return; - } - } -} - -static void -ssPop(sqInt n) -{ - assert(((simStackPtr - n) >= (methodOrBlockNumTemps - 1)) - || ((!needsFrame) - && ((simStackPtr - n) >= -1))); - simStackPtr -= n; -} - -static sqInt -ssPushBaseoffset(sqInt reg, sqInt offset) -{ - CogSimStackEntry * cascade0; - - ssPush(1); - if (simSpillBase > simStackPtr) { - simSpillBase = ((simStackPtr < 0) ? 0 : simStackPtr); - } - cascade0 = ssTop(); - (cascade0->type = SSBaseOffset); - (cascade0->registerr = reg); - (cascade0->offset = offset); - (cascade0->spilled = 0); - (cascade0->bcptr = bytecodePointer); - return 0; -} - -static sqInt -ssPushConstant(sqInt literal) -{ - CogSimStackEntry * cascade0; - - ssPush(1); - if (simSpillBase > simStackPtr) { - simSpillBase = ((simStackPtr < 0) ? 0 : simStackPtr); - } - cascade0 = ssTop(); - (cascade0->type = SSConstant); - (cascade0->constant = literal); - (cascade0->spilled = 0); - (cascade0->bcptr = bytecodePointer); - return 0; -} - -static sqInt -ssPushDesc(CogSimStackEntry simStackEntry) -{ - if (((simStackEntry.type)) == SSSpill) { - (simStackEntry.type = SSBaseOffset); - } - (simStackEntry.spilled = 0); - (simStackEntry.bcptr = bytecodePointer); - simStack[(simStackPtr += 1)] = simStackEntry; - if (simSpillBase > simStackPtr) { - simSpillBase = ((simStackPtr < 0) ? 0 : simStackPtr); - } - return 0; -} - -static sqInt -ssPushRegister(sqInt reg) -{ - CogSimStackEntry * cascade0; - - ssPush(1); - if (simSpillBase > simStackPtr) { - simSpillBase = ((simStackPtr < 0) ? 0 : simStackPtr); - } - cascade0 = ssTop(); - (cascade0->type = SSRegister); - (cascade0->registerr = reg); - (cascade0->spilled = 0); - (cascade0->bcptr = bytecodePointer); - return 0; -} - -static void -ssPush(sqInt n) -{ - simStackPtr += n; -} - - -/* Store or pop the top simulated stack entry to a register. - Pop to preferredReg if the entry is not itself a register. - Answer the actual register the result ends up in. */ - -static sqInt -ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg) -{ - sqInt actualReg; - - actualReg = preferredReg; - if (popBoolean) { - if ((((ssTop()->type)) == SSRegister) - && (!((ssTop()->spilled)))) { - actualReg = (ssTop()->registerr); - } - else { - popToReg(ssTop(), preferredReg); - } - ssPop(1); - } - else { - if (((ssTop()->type)) == SSRegister) { - actualReg = (ssTop()->registerr); - } - else { - storeToReg(ssTop(), preferredReg); - } - } - return actualReg; -} - -static CogSimStackEntry * -ssTop(void) -{ - return simStackAt(simStackPtr); -} - -static CogSimStackEntry -ssTopDescriptor(void) -{ - return simStack[simStackPtr]; -} - -static CogSimStackEntry * -ssValue(sqInt n) -{ - return simStackAt(simStackPtr - n); -} - -static sqInt stackBytesForNumArgs(AbstractInstruction * self_in_stackBytesForNumArgs, sqInt numArgs) { return numArgs * 4; @@ -14499,33 +12952,6 @@ byteAtput(followingAddress - 4, literal & 255); } -static void -storeToReg(CogSimStackEntry * self_in_storeToReg, sqInt reg) -{ - - switch ((self_in_storeToReg->type)) { - case SSBaseOffset: - case SSSpill: - gMoveMwrR((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 { - gMoveCqR((self_in_storeToReg->constant), reg); - } - break; - case SSRegister: - if (reg != ((self_in_storeToReg->registerr))) { - gMoveRR((self_in_storeToReg->registerr), reg); - } - break; - default: - error("Case not found and no otherwise clause"); - } -} - static sqInt sib(AbstractInstruction * self_in_sib, sqInt scale, sqInt indexReg, sqInt baseReg) { Modified: branches/Cog/src/vm/cogit.h =================================================================== --- branches/Cog/src/vm/cogit.h 2011-01-01 20:26:17 UTC (rev 2338) +++ branches/Cog/src/vm/cogit.h 2011-01-01 22:45:04 UTC (rev 2339) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker-oscog.41 uuid: 096b8a29-e7e8-4cbf-b29c-0f096abbdd5c + CCodeGenerator VMMaker-oscog.42 uuid: d3b303c1-306e-4343-b078-655fc2bfc436 */ @@ -11,12 +11,7 @@ sqInt canMapBytecodePCsToNativePCs(void); extern void (*ceCaptureCStackPointers)(); sqInt ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver); -extern void (*ceEnter0ArgsPIC)(); -extern void (*ceEnter1ArgsPIC)(); -extern void (*ceEnter2ArgsPIC)(); extern void (*ceEnterCogCodePopReceiverAndClassRegs)(); -extern void (*ceEnterCogCodePopReceiverArg0Regs)(); -extern void (*ceEnterCogCodePopReceiverArg1Arg0Regs)(); extern void (*ceEnterCogCodePopReceiverReg)(); sqInt ceSICMiss(sqInt receiver); void checkAssertsEnabledInCogit(void); @@ -31,8 +26,6 @@ void compactCogCompiledCode(void); void enterCogCodePopReceiver(void); void enterCogCodePopReceiverAndClassRegs(void); -void enterCogCodePopReceiverArg0Regs(void); -void enterCogCodePopReceiverArg1Arg0Regs(void); CogBlockMethod * findEnclosingMethodForinHomeMethod(sqInt mcpc, CogMethod *cogMethod); CogBlockMethod * findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod); sqInt genQuickReturnConst(void); @@ -83,12 +76,7 @@ sqInt ceCannotResumeTrampoline; void (*ceCaptureCStackPointers)(void); sqInt ceCheckForInterruptTrampoline; -void (*ceEnter0ArgsPIC)(void); -void (*ceEnter1ArgsPIC)(void); -void (*ceEnter2ArgsPIC)(void); void (*ceEnterCogCodePopReceiverAndClassRegs)(void); -void (*ceEnterCogCodePopReceiverArg0Regs)(void); -void (*ceEnterCogCodePopReceiverArg1Arg0Regs)(void); void (*ceEnterCogCodePopReceiverReg)(void); unsigned long (*ceGetSP)(void); sqInt ceReturnToInterpreterTrampoline; @@ -99,8 +87,6 @@ sqInt cmNoCheckEntryOffset; unsigned long debugPrimCallStackOffset; void (*realCEEnterCogCodePopReceiverAndClassRegs)(void); -void (*realCEEnterCogCodePopReceiverArg0Regs)(void); -void (*realCEEnterCogCodePopReceiverArg1Arg0Regs)(void); void (*realCEEnterCogCodePopReceiverReg)(void); int traceLinkedSends ; sqInt traceStores; @@ -115,7 +101,7 @@ #define getCStackPointer() CStackPointer #define noCheckEntryOffset() cmNoCheckEntryOffset #define noContextSwitchBlockEntryOffset() blockNoContextSwitchOffset -#define numRegArgs() 1 +#define numRegArgs() 0 #define printOnTrace() (traceLinkedSends & 8) #define recordEventTrace() (traceLinkedSends & 4) #define recordPrimTrace() (traceLinkedSends & 2) |
Free forum by Nabble | Edit this page |