Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3120.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3120 Author: eem Time: 13 December 2021, 1:07:43.003494 pm UUID: b9f54a3e-8890-4a80-bc01-bef41e2111bc Ancestors: VMMaker.oscog-eem.3119
CogARMv8Compiler: only include the hasAtomicInstructrions determination if compiling theCOGMTVM.
=============== Diff against VMMaker.oscog-eem.3119 ===============
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 cppIf: COGMTVM ifTrue: + [self setHasAtomicInstructions: ((self getauxval: #AT_HWCAP) anyMask: #HWCAP_ATOMICS)]! - 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 cppIf: COGMTVM ifTrue: + [self setHasAtomicInstructions: true]! - 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 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]. 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. + self cppIf: COGMTVM ifTrue: + [cogit resetMethodZoneBase: startAddress. + cogit ensureExecutableCodeZoneWithin: + [idISAR0 := (self cCode: 'getFeatureReg()' inSmalltalk: [cogit simulateLeafCallOf: startAddress]). + self setHasAtomicInstructions: (idISAR0 >> 20 bitAnd: 2r1111) = 2r10]]! - cogit resetMethodZoneBase: startAddress. - cogit ensureExecutableCodeZoneWithin: - [idISAR0 := (self cCode: 'getFeatureReg()' inSmalltalk: [cogit simulateLeafCallOf: startAddress]). - self setHasAtomicInstructions: (idISAR0 >> 20 bitAnd: 2r1111) = 2r10]!
Item was changed: ----- 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> - <inline: true> | 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!
vm-dev@lists.squeakfoundation.org