<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>