[Vm-dev] VM Maker: VMMaker.oscog-eem.3120.mcz
commits at source.squeak.org
commits at source.squeak.org
Mon Dec 13 21:08:01 UTC 2021
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_en/lau1443435580346.html
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_en/lau1443435580346.html
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!
More information about the Vm-dev
mailing list