<div>Hi all,<br></div><div><br></div><div>Thanks very much!<br></div><div><br></div><div>With this change I can build ARMv8, Armv6, and x86-64 all on Linux. This is very very very nice.<br></div><div><br></div><div>And the ARMv8 2 raisedTo: 64 bug is gone but we knew that already. <br></div><div><br></div><div>Thanks again.<br></div><div><br></div><div>cheers<br></div><div><br></div><div>bruce</div><div><br></div><div><br></div><div ><br></div><div class="ik_mail_quote"><div>On 0000-08-17T17:30:28.000+00:34, <commits@source.squeak.org> wrote:</div><blockquote class="ws-ng-quote"><pre style="white-space: normal;">Eliot Miranda uploaded a new version of VMMaker to project VM Maker:<br><a class="defaultMailLink" href="http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3034.mcz" target="_blank" title="http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3034.mcz">source.squeak.org/VMMaker/V...</a><br><br>==================== Summary ====================<br><br>Name: VMMaker.oscog-eem.3034<br>Author: eem<br>Time: 12 August 2021, 10:56:19.010201 am<br>UUID: 3ea0aaa2-20e4-4c02-b448-c3e708578e16<br>Ancestors: VMMaker.oscog-eem.3033<br><br>CogARMv8Compiler: Make sure the generated cache flush code flushes the range (startAddress to endAddress], i.e. never flush endAddress, only addresses less than endAddress. Flushing endAddress can cause a segmentation violation if the endAddress is on an empty page.<br><br>Have Symbol simulate & for expressions such as<br> self cppIf: #__APPLE__ & #__MACH__<br> ifFalse: ...<br><br>=============== Diff against VMMaker.oscog-eem.3033 ===============<br><br>Item was changed:<br> ----- Method: CogARMv8Compiler>>generateDCacheFlush (in category 'inline cacheing') -----<br> generateDCacheFlush<br> "Use the DC instruction to implement ceFlushDCache(void *start, void *end); see flushDCacheFrom:to:.<br> If there is a dual mapped zone then clean data via DC_CVAU as address + codeToDataDelta,<br> then invalidate data at address via CIVAC."<br> <br> "D4.4.7 About cache maintenance in AArch64 state D4-2478<br> <br> Terminology for Clean, Invalidate, and Clean and Invalidate instructions D4-2479<br> ...<br> - For instructions operating by VA, the following conceptual points are defined: D4-2480<br> Point of Unification (PoU) <br> The PoU for a PE is the point by which the instruction and data caches and the translation table walks of that<br> PE are guaranteed to see the same copy of a memory location. In many cases, the Point of Unification is the<br> point in a uniprocessor memory system by which the instruction and data caches and the translation table<br> walks have merged.<br> <br> The PoU for an Inner Shareable shareability domain is the point by which the instruction and data caches<br> and the translation table walks of all the PEs in that Inner Shareable shareability domain are guaranteed to<br> see the same copy of a memory location. Defining this point permits self-modifying software to ensure future<br> instruction fetches are associated with the modified version of the software by using the standard correctness<br> policy of:<br> 1. Clean data cache entry by address.<br> 2. Invalidate instruction cache entry by address.<br> <br> Example code for cache maintenance instructions D4-2490 - D4-2491"<br> self cppIf: #__APPLE__ & #__MACH__<br> ifFalse:<br> [| mask loop |<br> self assert: cogit getCodeToDataDelta ~= 0.<br> "Mask is large enough to encompass the method zone and has the correct minimum alignment."<br> mask := 1 << (cogit coInterpreter highBit: cogit methodZone zoneEnd) - self dataCacheLineLength.<br> <br> "Since this is used from C code we must use only caller-saved registers.<br> C arg registers 2 & 3 are such a convenient pair of caller-saved registers."<br> cogit AndCq: mask R: CArg0Reg R: CArg2Reg. "CArg2Reg = aligned pointer to start of each data cache line"<br> cogit AddCq: cogit getCodeToDataDelta R: CArg2Reg R: CArg3Reg.<br> loop := cogit Label.<br> "see concretizeDataCacheControl"<br> cogit gen: DC operand: CArg3Reg operand: DC_CVAU. "clean (flush) address + codeToDataDelta"<br> cogit gen: DC operand: CArg2Reg operand: DC_CIVAC. "invalidate address"<br> cogit<br> AddCq: self dataCacheLineLength R: CArg2Reg;<br> AddCq: self dataCacheLineLength R: CArg3Reg;<br> CmpR: CArg1Reg R: CArg2Reg;<br>+ JumpBelow: loop.<br>- JumpBelowOrEqual: loop.<br> cogit RetN: 0]!<br><br>Item was changed:<br> ----- Method: CogARMv8Compiler>>generateICacheFlush (in category 'inline cacheing') -----<br> generateICacheFlush<br> "Use DC VAUC, DSB, IC IVAU, and ISB instructions to implement ceFlushICache(void *start, void *end); see flushICacheFrom:to:.<br> One might think that if there is a dual zone then data at address + codeToDataDelta must be cleaned,<br> but this isn't the case. All we need to do is clean data at address via DC VAUC and instructions via IC IVAU."<br> <br> "B2.2.5 Concurrent modification and execution of instructions B2-112<br> <br> ...to avoid UNPREDICTABLE or CONSTRAINED UNPREDICTABLE behavior, instruction modifications must be explicitly synchronized before they are executed. The required synchronization is as follows:<br> <br> 1. No PE must be executing an instruction when another PE is modifying that instruction.<br> <br> 2. To ensure that the modified instructions are observable, a PE that is writing the instructions must issue the following sequence of instructions and operations:<br> <br> ; Coherency example for data and instruction accesses within the same Inner Shareable domain.<br> ; enter this code with <Wt> containing a new 32-bit instruction, to be held in Cacheable space at a location pointed to by Xn.<br> <br> STR Wt, [Xn]<br> DC CVAU, Xn ; Clean data cache by VA to point of unification (PoU)<br> DSB ISH ; Ensure visibility of the data cleaned from cache<br> IC IVAU, Xn ; Invalidate instruction cache by VA to PoU<br> DSB ISH<br> <br> Note<br> - The DC CVAU operation is not required if the area of memory is either Non-cacheable or Write-Through Cacheable.<br> - If the contents of physical memory differ between the mappings, changing the mapping of VAs to PAs can cause<br> the instructions to be concurrently modified by one PE and executed by another PE. If the modifications affect<br> instructions other than those listed as being acceptable for modification, synchronization must be used to avoid<br> UNPREDICTABLE or CONSTRAINED UNPREDICTABLE behavior.<br> <br> 3. In a multiprocessor system, the IC IVAU is broadcast to all PEs within the Inner Shareable domain of the PE running this sequence.<br> However, when the modified instructions are observable, each PE that is executing the modified instructions must issue the following<br> instruction to ensure execution of the modified instructions:<br> <br> ISB ; Synchronize fetched instruction stream"<br> <br> "D4.4.7 About cache maintenance in AArch64 state D4-2478<br> <br> Terminology for Clean, Invalidate, and Clean and Invalidate instructions D4-2479<br> ...<br> - For instructions operating by VA, the following conceptual points are defined: D4-2480<br> Point of Unification (PoU) <br> The PoU for a PE is the point by which the instruction and data caches and the translation table walks of that<br> PE are guaranteed to see the same copy of a memory location. In many cases, the Point of Unification is the<br> point in a uniprocessor memory system by which the instruction and data caches and the translation table<br> walks have merged.<br> <br> The PoU for an Inner Shareable shareability domain is the point by which the instruction and data caches<br> and the translation table walks of all the PEs in that Inner Shareable shareability domain are guaranteed to<br> see the same copy of a memory location. Defining this point permits self-modifying software to ensure future<br> instruction fetches are associated with the modified version of the software by using the standard correctness<br> policy of:<br> 1. Clean data cache entry by address.<br> 2. Invalidate instruction cache entry by address.<br> <br> Example code for cache maintenance instructions D4-2490 - D4-2491"<br> self cppIf: #__APPLE__ & #__MACH__<br> ifFalse:<br> [| mask loop |<br> "See concretizeCacheControlOp1:CRm:Op2: & <br> <a class="defaultMailLink" href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100403_0200_00_en/lau1443435580346.html" target="_blank" title="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100403_0200_00_en/lau1443435580346.html">infocenter.arm.com/help/ind...</a>"<br> self dataCacheFlushRequired ifTrue: "CTR_EL0.IDC is zero; must clean data cache to point of unification."<br> ["Since this is used from C code we must use only caller-saved registers.<br> C arg registers 2 & 3 are as such a convenient pair of caller-saved registers."<br> "Mask is large enough to encompass the method zone and has the correct minimum alignment."<br> mask := 1 << (cogit coInterpreter highBit: cogit methodZone zoneEnd) - self dataCacheLineLength.<br> cogit AndCq: mask R: CArg0Reg R: CArg2Reg. "CArg2Reg = aligned pointer to start of each data cache line"<br> <br> loop := cogit Label.<br> "see concretizeDataCacheControl"<br> cogit<br> gen: DC operand: CArg2Reg operand: DC_CVAU; "clean (flush) address"<br> AddCq: self dataCacheLineLength R: CArg2Reg;<br> CmpR: CArg1Reg R: CArg2Reg;<br>+ JumpBelow: loop].<br>- JumpBelowOrEqual: loop].<br> <br> cogit gen: DSB operand: DSB_ISH operand: DSB_ALL. "Ensure visibility of the data cleaned from cache"<br> <br> self instructionCacheFlushRequired ifTrue: "CTR_EL0.DIC is zero; must clean instruction cache to point of unification."<br> ["Mask is large enough to encompass the method zone and has the correct minimum alignment."<br> mask := 1 << (cogit coInterpreter highBit: cogit methodZone zoneEnd) - self instructionCacheLineLength.<br> cogit AndCq: mask R: CArg0Reg R: CArg2Reg. "CArg2Reg = aligned pointer to start of each data cache line"<br> <br> loop := cogit Label.<br> "see concretizeDataCacheControl"<br> cogit<br> gen: IC operand: CArg2Reg operand: IC_IVAU; "clean (flush) address"<br> AddCq: self instructionCacheLineLength R: CArg2Reg;<br> CmpR: CArg1Reg R: CArg2Reg;<br>+ JumpBelow: loop.<br>- JumpBelowOrEqual: loop.<br> <br> cogit gen: DSB operand: DSB_ISH operand: DSB_ALL].<br> <br> cogit<br> gen: ISB;<br> RetN: 0]!<br><br>Item was added:<br>+ ----- Method: Symbol>>& (in category '*VMMaker-interpreter simulator') -----<br>+ & aSymbol<br>+ ^(VMClass valueOfSymbol: self) & (VMClass valueOfSymbol: aSymbol)!<br><br>Item was added:<br>+ ----- Method: VMClass class>>valueOfSymbol: (in category 'simulation') -----<br>+ valueOfSymbol: value<br>+ ^(self bindingOf: value)<br>+ ifNil: [InitializationOptions at: value ifAbsent: [false]]<br>+ ifNotNil: [:binding| binding value]!<br><br>Item was changed:<br> ----- Method: VMClass>>cppIf:ifTrue:ifFalse: (in category 'translation support') -----<br> cppIf: conditionBlockOrSymbolValue ifTrue: trueExpressionOrBlock ifFalse: falseExpressionOrBlockOrNil<br> "When translated, produces #if (condition) #else #endif CPP directives.<br> Example usage:<br> <br> self cppIf: [BytesPerWord = 8]<br> ifTrue: [self doSomethingFor64Bit]<br> ifFalse: [self doSomethingFor32Bit]<br> self cppIf: BytesPerWord = 8<br> ifTrue: [self doSomethingFor64Bit]<br> ifFalse: [self doSomethingFor32Bit]<br> self cppIf: #A_GLOBAL<br> ifTrue: [self doSomethingFor64Bit]<br> ifFalse: [self doSomethingFor32Bit]"<br> <doNotGenerate><br> ^(conditionBlockOrSymbolValue value<br> ifNil: [false]<br> ifNotNil: [:value|<br> value isInteger<br> ifTrue: [value ~= 0]<br> ifFalse:<br> [value isSymbol<br>+ ifTrue: [self class valueOfSymbol: value]<br>- ifTrue: [(self class bindingOf: value)<br>- ifNil: [InitializationOptions at: value ifAbsent: [false]]<br>- ifNotNil: [:binding| binding value]]<br> ifFalse: [value]]])<br> ifTrue: trueExpressionOrBlock<br> ifFalse: falseExpressionOrBlockOrNil!</pre></blockquote></div>