Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3338.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3338 Author: eem Time: 16 September 2023, 8:17:48.533178 pm UUID: 1d7f8a94-2a3d-47fa-867b-d6ea3029be14 Ancestors: VMMaker.oscog-LM.3337
Nuke unused methods: getMaxWaitingPriority & generateLowLevelTryLock:
Restore some slips in VMMaker.oscog-LM.3337: CogARMv8Compiler still uses DataCacheFlushRequired DataCacheLineLength InstructionCacheFlushRequired InstructionCacheLineLength.
=============== Diff against VMMaker.oscog-LM.3337 ===============
Item was removed: - ----- Method: CoInterpreterMT>>getMaxWaitingPriority (in category 'process primitive support') ----- - getMaxWaitingPriority - <cmacro: '() GIV(maxWaitingPriority)'> - ^maxWaitingPriority!
Item was changed: CogAbstractInstruction subclass: #CogARMv8Compiler instanceVariableNames: '' + classVariableNames: 'AL ArithmeticAdd ArithmeticAddS ArithmeticSub ArithmeticSubS CASAL CArg0Reg CArg1Reg CArg2Reg CArg3Reg CArg4Reg CArg5Reg CArg6Reg CBNZ CBZ CC CCMPNE CLREX CS CSET D0 D1 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D2 D20 D21 D22 D23 D24 D25 D26 D27 D28 D29 D3 D30 D31 D4 D5 D6 D7 D8 D9 DC DC_CISW DC_CIVAC DC_CSW DC_CVAC DC_CVAU DC_ISW DC_IVAC DC_ZVA DMB DSB DSB_ALL DSB_ALLSY DSB_ISH DSB_NSH DSB_OSH DSB_READS DSB_SY DSB_WRITES DataCacheFlushRequired DataCacheLineLength DivRRR EQ FP GE GT HI IC IC_IALLU IC_IALLUIS IC_IVAU ISB InstructionCacheFlushRequired InstructionCacheLineLength LDAXR LE LR LS LT LogicalAnd LogicalAndS LogicalOr LogicalXor MI MRS_CTR_EL0 MRS_ID_AA64ISAR0_EL1 MSubRRR MoveAwRR MoveRRAw MulOverflowRRR MulRRR NE NativePopRR NativePushRR PJWPNChange PJWPNClear PJWPNSet PJWPNState PL R0 R1 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R2 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 R3 R30 R31 R4 R5 R6 R7 R8 R9 SMULHRRR SP STLR STLXR SXTB SXTH SXTW SXTX UXTB UXTH UX TW UXTX VC VS XZR' - classVariableNames: 'AL ArithmeticAdd ArithmeticAddS ArithmeticSub ArithmeticSubS CASAL CArg0Reg CArg1Reg CArg2Reg CArg3Reg CArg4Reg CArg5Reg CArg6Reg CBNZ CBZ CC CCMPNE CLREX CS CSET D0 D1 D10 D11 D12 D13 D14 D15 D16 D17 D18 D19 D2 D20 D21 D22 D23 D24 D25 D26 D27 D28 D29 D3 D30 D31 D4 D5 D6 D7 D8 D9 DC DC_CISW DC_CIVAC DC_CSW DC_CVAC DC_CVAU DC_ISW DC_IVAC DC_ZVA DMB DSB DSB_ALL DSB_ALLSY DSB_ISH DSB_NSH DSB_OSH DSB_READS DSB_SY DSB_WRITES DivRRR EQ FP GE GT HI IC IC_IALLU IC_IALLUIS IC_IVAU ISB LDAXR LE LR LS LT LogicalAnd LogicalAndS LogicalOr LogicalXor MI MRS_CTR_EL0 MRS_ID_AA64ISAR0_EL1 MSubRRR MoveAwRR MoveRRAw MulOverflowRRR MulRRR NE NativePopRR NativePushRR PJWPNChange PJWPNClear PJWPNSet PJWPNState PL R0 R1 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R2 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 R3 R30 R31 R4 R5 R6 R7 R8 R9 SMULHRRR SP STLR STLXR SXTB SXTH SXTW SXTX UXTB UXTH UXTW UXTX VC VS XZR' poolDictionaries: 'ARMv8A64Opcodes' category: 'VMMaker-JIT'!
!CogARMv8Compiler commentStamp: 'eem 1/7/2021 23:01' prior: 0! I generate ARMv8 machine code instructions from CogAbstractInstructions with CogRTLOpcodes. Here in "Arm ARM" refers to Arm® Architecture Reference Manual Armv8, for Armv8-A architecture profile https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-man...
Some things to know about ARMv8 instructions: Whether 31 in a register field implies the zero register or the SP register(s) depends on the specific instruction.
C3.2.1 Load/Store register If a Load instruction specifies writeback and the register being loaded is also the base register, then behavior is CONSTRAINED UNPREDICTABLE and one of the following behaviors must occur: - The instruction is treated as UNDEFINED. - The instruction is treated as a NOP. - The instruction performs the load using the specified addressing mode and the base register becomes UNKNOWN. In addition, if an exception occurs during the execution of such an instruction, the base address might be corrupted so that the instruction cannot be repeated. If a Store instruction performs a writeback and the register that is stored is also the base register, then behavior is CONSTRAINED UNPREDICTABLE and one of the following behaviors must occur: - The instruction is treated as UNDEFINED. - The instruction is treated as a NOP. - The instruction performs the store to the designated register using the specified addressing mode, but the value stored is UNKNOWN.!
Item was changed: ----- Method: CogARMv8Compiler>>detectFeaturesOnLinux (in category 'feature detection') ----- detectFeaturesOnLinux "Do a throw-away compilation to read CTR_EL0 and initialize ctrEl0. Some linux kernels trap and synthesize access to ID_AA64ISAR0_EL1, and some do not, so use getauxval(3) to access value(s) derived there-from, i.e. whether the processor has atomic instructions." <option: #__linux__> | startAddress getFeatureReg ctrEL0 | <var: 'getFeatureReg' declareC: 'usqIntptr_t (*getFeatureReg)(void)'> startAddress := cogit methodZoneBase. cogit allocateOpcodes: 4 bytecodes: 0. getFeatureReg := cogit cCoerceSimple: startAddress to: #'usqIntptr_t (*)(void)'. "Return the value of CTR_EL0; that's the control register that defines the vital statistics of the processor's caches." cogit gen: Nop; "do something anodyne so it is easy to distinguish MRS_CTR_EL0 being an illegal instruction rather than the code zone not being executable." gen: MRS_CTR_EL0 operand: ABIResultReg; RetN: 0. cogit outputInstructionsForGeneratedRuntimeAt: startAddress. cogit resetMethodZoneBase: startAddress. cogit ensureExecutableCodeZoneWithin: [ctrEL0 := (self cCode: 'getFeatureReg()' inSmalltalk: [cogit simulateLeafCallOf: startAddress]). "see e.g. CogARMv8Compiler class>>printCTR_EL0:, concretizeCacheControlOp1:CRm:Op2: & http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100403_0200_00_e... DminLine & IminLine are Log2 words; 16 words miniumum" self setDataCacheFlushRequired: (ctrEL0 noMask: 1 << 28). self setDataCacheLineLength: 4 << (ctrEL0 >> 16 bitAnd: 15). self dataCacheLineLength = 0 ifTrue: [self setDataCacheLineLength: 4 << 4]. self setInstructionCacheFlushRequired: (ctrEL0 noMask: 1 << 29). self setInstructionCacheLineLength: 4 << (ctrEL0 bitAnd: 15)]. + self instructionCacheLineLength = 0 ifTrue: + [self setInstructionCacheLineLength: 4 << 4]! - self instructionCacheLineLength = 0 ifTrue: - [self setInstructionCacheLineLength: 4 << 4]. - self cppIf: COGMTVM ifTrue: - [self setHasAtomicInstructions: ((self getauxval: #AT_HWCAP) anyMask: #HWCAP_ATOMICS)]!
Item was changed: ----- Method: CogARMv8Compiler>>detectFeaturesOnMacOS (in category 'memory access') ----- detectFeaturesOnMacOS <option: #__APPLE__> <inline: #always> "MacOS does not allow access to ctl_el0, so derive cache information etc from sysctl" "Here are values from sysctl(8), hardwired for now rather than derived through sysctl(3) hw.cacheconfig: 8 1 1 0 0 0 0 0 0 0 (we speculate that the 1's indicate cache flush required) hw.cachelinesize: 128 hw.l1icachesize: 131072 hw.l1dcachesize: 131072 hw.optional.neon: 1 hw.optional.neon_hpfp: 1 hw.optional.neon_fp16: 1 hw.optional.armv8_1_atomics: 1"
false ifTrue: "Apple's cache flush code on M1 is simple and effective; we can't easily better it..." [self setDataCacheLineLength: 128. self setDataCacheFlushRequired: true. self setInstructionCacheLineLength: 128. + self setInstructionCacheFlushRequired: true]! - self setInstructionCacheFlushRequired: true]. - self cppIf: COGMTVM ifTrue: - [self setHasAtomicInstructions: true]!
Item was changed: ----- Method: CogARMv8Compiler>>detectFeaturesOnRawMachine (in category 'feature detection') ----- detectFeaturesOnRawMachine "Do throw-away compilations to read CTR_EL0 & ID_AA64ISAR0_EL1 and initialize ctrEl0 & idISAR0" <notOption: #__APPLE__> <notOption: #__linux__> + | startAddress getFeatureReg ctrEL0 | - | startAddress getFeatureReg ctrEL0 idISAR0 | <var: 'getFeatureReg' declareC: 'usqIntptr_t (*getFeatureReg)(void)'> startAddress := cogit methodZoneBase. cogit allocateOpcodes: 4 bytecodes: 0. getFeatureReg := cogit cCoerceSimple: startAddress to: #'usqIntptr_t (*)(void)'. "Return the value of CTR_EL0; that's the control register that defines the vital statistics of the processor's caches." cogit gen: Nop; "do something anodyne so it is easy to distinguish MRS_CTR_EL0 being an illegal instruction rather than the code zone not being executable." gen: MRS_CTR_EL0 operand: ABIResultReg; RetN: 0. cogit outputInstructionsForGeneratedRuntimeAt: startAddress. cogit resetMethodZoneBase: startAddress. cogit ensureExecutableCodeZoneWithin: [ctrEL0 := (self cCode: 'getFeatureReg()' inSmalltalk: [cogit simulateLeafCallOf: startAddress]). "see e.g. CogARMv8Compiler class>>printCTR_EL0:, concretizeCacheControlOp1:CRm:Op2: & http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100403_0200_00_e... DminLine & IminLine are Log2 words; 16 words miniumum" self setDataCacheFlushRequired: (ctrEL0 noMask: 1 << 28). self setDataCacheLineLength: 4 << (ctrEL0 >> 16 bitAnd: 15). self dataCacheLineLength = 0 ifTrue: [self setDataCacheLineLength: 4 << 4]. self setInstructionCacheFlushRequired: (ctrEL0 noMask: 1 << 29). self setInstructionCacheLineLength: 4 << (ctrEL0 bitAnd: 15)]. + self instructionCacheLineLength = 0 ifTrue: + [self setInstructionCacheLineLength: 4 << 4]. - self instructionCacheLineLength = 0 ifTrue: - [self setInstructionCacheLineLength: 4 << 4]. cogit zeroOpcodeIndexForNewOpcodes. cogit gen: Nop; "do something anodyne so it is easy to distinguish MRS_ID_AA64ISAR0_EL1 being an illegal instruction rather than the code zone not being executable." gen: MRS_ID_AA64ISAR0_EL1 operand: ABIResultReg; RetN: 0. + cogit outputInstructionsForGeneratedRuntimeAt: startAddress! - cogit outputInstructionsForGeneratedRuntimeAt: startAddress. - self cppIf: COGMTVM ifTrue: - [cogit resetMethodZoneBase: startAddress. - cogit ensureExecutableCodeZoneWithin: - [idISAR0 := (self cCode: 'getFeatureReg()' inSmalltalk: [cogit simulateLeafCallOf: startAddress]). - self setHasAtomicInstructions: (idISAR0 >> 20 bitAnd: 2r1111) = 2r10]]!
Item was removed: - ----- Method: CogARMv8Compiler>>generateLowLevelTryLock: (in category 'multi-threading') ----- - generateLowLevelTryLock: vmOwnerLockAddress - "Generate a function that attempts to lock the vmOwnerLock to the argument and answers if it succeeded." - <inline: #always> - | lockValueReg vmOwnerLockAddressReg br statusReg ldaxr | - vmOwnerLockAddress = 0 ifTrue: - [cogit - MoveCq: 1 R: ABIResultReg; - RetN: 0. - ^self]. - - "spiffy 8.1 version using CASAL..." - lockValueReg := CArg1Reg. "Holds the value of lock if unlocked (zero), receives the existing value of the lock" - vmOwnerLockAddressReg := CArg2Reg. - self hasAtomicInstructions ifTrue: - [cogit - MoveCq: 0 R: lockValueReg; - MoveCq: vmOwnerLockAddress R: vmOwnerLockAddressReg; - gen: CASAL operand: lockValueReg operand: CArg0Reg operand: vmOwnerLockAddressReg. - br := cogit gen: CBNZ operand: 0 operand: lockValueReg. - cogit - MoveCq: 1 R: ABIResultReg; - RetN: 0. - br jmpTarget: (cogit CmpR: ABIResultReg R: lockValueReg). - cogit - gen: CSET operand: ABIResultReg operand: EQ; "i.e. if NE to 0, then is it already set to the argument?" - RetN: 0. - ^self]. - - "frumpy 8.0 version using LDAXR/STLXR" - cogit MoveCq: vmOwnerLockAddress R: vmOwnerLockAddressReg. - cogit MoveCq: 0 R: (statusReg := CArg3Reg). "STLXR sets a word status register; clearing the top bits means it's a non-issue" - ldaxr := cogit gen: LDAXR operand: lockValueReg operand: vmOwnerLockAddressReg. - br := cogit gen: CBNZ operand: 0 operand: lockValueReg. - cogit gen: STLXR operand: CArg0Reg operand: vmOwnerLockAddressReg operand: statusReg. - cogit gen: CBNZ operand: ldaxr asUnsignedInteger operand: statusReg. - "Since CArg0Reg is never zero, merely returning answers true" - cogit RetN: 0. - br jmpTarget: (cogit gen: CLREX). - cogit CmpR: ABIResultReg R: lockValueReg. - cogit gen: CSET operand: ABIResultReg operand: EQ. "i.e. if NE to 0, then is it already set to the argument?" - cogit RetN: 0. - ^self!
Item was removed: - ----- Method: CogARMv8Compiler>>hasAtomicInstructions (in category 'feature detection') ----- - hasAtomicInstructions - <cmacro: '(ign) hasAtomicInstructions'> - "For want of somewhere to put the variable that doesn't bloat an instance of the receiver..." - ^HasAtomicInstructions!
Item was removed: - ----- Method: CogARMv8Compiler>>setHasAtomicInstructions: (in category 'feature detection') ----- - setHasAtomicInstructions: boolean - <cmacro: '(ign,b) hasAtomicInstructions = b'> - "For want of somewhere to put the variable that doesn't bloat an instance of the receiver..." - HasAtomicInstructions := boolean!
Item was removed: - ----- Method: CogAbstractInstruction>>generateLowLevelTryLock: (in category 'multi-threading') ----- - generateLowLevelTryLock: vmOwnerLockAddress - self subclassResponsibility!
Item was removed: - ----- Method: CogIA32Compiler>>generateLowLevelTryLock: (in category 'multi-threading') ----- - generateLowLevelTryLock: vmOwnerLockAddress - "Generate a function that attempts to lock the vmOwnerLock and answers if it succeeded." - <inline: true> - | valueReg | - vmOwnerLockAddress = 0 ifTrue: - [cogit - MoveCq: 1 R: ABIResultReg; - RetN: 0. - ^self]. - valueReg := cogit availableRegisterOrNoneIn: (ABICallerSavedRegisterMask bitClear: 1 << EAX). - cogit - MoveMw: 4 r: ESP R: valueReg; - MoveCq: 0 R: EAX; - gen: LOCK; - gen: CMPXCHGRAw operand: valueReg operand: vmOwnerLockAddress; - gen: SETE operand: ABIResultReg; "a.k.a. EAX" - RetN: 0!
Item was removed: - ----- Method: CogVMSimulator>>getMaxWaitingPriority (in category 'multi-threading simulation switch') ----- - getMaxWaitingPriority - "This method includes or excludes CoInterpreterMT methods as required. - Auto-generated by CogVMSimulator>>ensureMultiThreadingOverridesAreUpToDate" - - ^self perform: #getMaxWaitingPriority - withArguments: {} - inSuperclass: (cogThreadManager ifNil: [CoInterpreterPrimitives] ifNotNil: [CoInterpreterMT])!
Item was removed: - ----- Method: CogX64Compiler>>generateLowLevelTryLock: (in category 'multi-threading') ----- - generateLowLevelTryLock: vmOwnerLockAddress - "Generate a function that attempts to lock the vmOwnerLock and answers if it succeeded." - <inline: true> - | vmOwnerLockAddressReg jumpEqual | - vmOwnerLockAddress = 0 ifTrue: - [cogit - MoveCq: 1 R: ABIResultReg; - RetN: 0. - ^self]. - "RAX holds the value of lock if unlocked (zero), receives the existing value of the lock; RAX is implicit in CMPXCHG" - vmOwnerLockAddressReg := CArg1Reg. - cogit - MoveCq: 0 R: RAX; - MoveCq: vmOwnerLockAddress R: vmOwnerLockAddressReg; - gen: LOCK; - gen: CMPXCHGRMr operand: CArg0Reg operand: vmOwnerLockAddressReg. - jumpEqual := cogit JumpZero: 0. - cogit CmpR: CArg0Reg R: RAX. "If not equal to zero is it already equal to the desired value?" - jumpEqual jmpTarget: (cogit gen: SETE operand: ABIResultReg). - cogit RetN: 0!
Item was removed: - ----- Method: Cogit>>generateVMOwnerLockFunctions (in category 'initialization') ----- - generateVMOwnerLockFunctions - <inline: true> - self cppIf: COGMTVM ifTrue: - [| startAddress | - self allocateOpcodes: backEnd numLowLevelLockOpcodes bytecodes: 0. - self zeroOpcodeIndex. - startAddress := methodZoneBase. - backEnd generateLowLevelTryLock: coInterpreter vmOwnerAddress. - self outputInstructionsForGeneratedRuntimeAt: startAddress. - self recordGeneratedRunTime: 'ceTryLockVMOwner' address: startAddress. - ceTryLockVMOwner := self cCoerceSimple: startAddress to: #'usqIntptr_t (*)(usqIntptr_t)']!
vm-dev@lists.squeakfoundation.org