<div dir="ltr"><div>Just a side note: I'm currently using the Spur64 VM generated from this VMMaker version.</div><div>Whoever changes the generator likes to live dangerously and eat own dog food.</div><div>I ran all 6.0 tests, no crash, no new failure.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le mar. 10 mars 2020 à 00:28, <<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br>
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:<br>
<a href="http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2723.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2723.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-nice.2723<br>
Author: nice<br>
Time: 10 March 2020, 12:26:31.04183 am<br>
UUID: c1319382-406c-43a7-9f55-2b48c4007d80<br>
Ancestors: VMMaker.oscog-eem.2722<br>
<br>
Fix the right shift: dont convert to usqInt a type longer than usqInt<br>
<br>
=============== Diff against VMMaker.oscog-eem.2722 ===============<br>
<br>
Item was changed:<br>
  ----- Method: CCodeGenerator>>generateBitShift:on:indent: (in category 'C translation') -----<br>
  generateBitShift: msgNode on: aStream indent: level<br>
        "Generate the C code for this message onto the given stream."<br>
<br>
+       | arg shift rightShift |<br>
+       (self isConstantNode: (arg := msgNode args first) valueInto: [:shiftValue| shift := shiftValue])<br>
-       | arg rcvr shift |<br>
-       arg := msgNode args first.<br>
-       rcvr := msgNode receiver.<br>
-       (self isConstantNode: arg valueInto: [:shiftValue| shift := shiftValue])<br>
                ifTrue: "bit shift amount is a constant"<br>
+                       [aStream nextPut: $(.<br>
-                       [aStream nextPutAll: '((usqInt) '.<br>
-                       self emitCExpression: rcvr on: aStream.<br>
                        shift < 0<br>
+                               ifTrue:<br>
+                                       [rightShift := TSendNode new<br>
+                                               setSelector: #>><br>
+                                               receiver: msgNode receiver<br>
+                                               arguments: {TConstantNode new setValue: shift negated}.<br>
+                                       self generateShiftRight: rightShift on: aStream indent: level]<br>
+                               ifFalse: [self generateShiftLeft: msgNode on: aStream indent: level].<br>
-                               ifTrue: [aStream nextPutAll: ' >> '; print: shift negated]<br>
-                               ifFalse: [aStream nextPutAll: ' << '; print: shift].<br>
                        aStream nextPut: $)]<br>
                ifFalse: "bit shift amount is an expression"<br>
+                       [rightShift := TSendNode new<br>
+                                               setSelector: #>><br>
+                                               receiver: msgNode receiver<br>
+                                               arguments: {TSendNode new<br>
+                                                       setSelector: #negated<br>
+                                                       receiver: arg<br>
+                                                       arguments: #()}.<br>
+                       aStream nextPutAll: '(('.<br>
+                       self emitCExpression: arg on: aStream.<br>
+                       aStream nextPutAll: ' < 0) ? ('.<br>
+                       self generateShiftRight: rightShift on: aStream indent: level. <br>
+                       aStream nextPutAll: ') : ('.<br>
+                       self generateShiftLeft: msgNode on: aStream indent: level.<br>
-                       [aStream nextPutAll: '(('.<br>
-                       self emitCExpression: arg on: aStream indent: level.<br>
-                       aStream nextPutAll: ' < 0) ? ((usqInt) '.<br>
-                       self emitCExpression: rcvr on: aStream indent: level.<br>
-                       aStream nextPutAll: ' >> -'.<br>
-                       self emitCExpression: arg on: aStream indent: level.<br>
-                       aStream nextPutAll: ') : ((usqInt) '.<br>
-                       self emitCExpression: rcvr on: aStream indent: level.<br>
-                       aStream nextPutAll: ' << '.<br>
-                       self emitCExpression: arg on: aStream indent: level.<br>
                        aStream nextPutAll: '))']!<br>
<br>
Item was changed:<br>
  ----- Method: CCodeGenerator>>generateShiftRight:on:indent: (in category 'C translation') -----<br>
  generateShiftRight: msgNode on: aStream indent: level<br>
+       "Generate the C code for this message onto the given stream.<br>
+       Note that this generates a Logical Shift (unsigned), not an Arithmetic Shift (signed)."<br>
-       "Generate the C code for this message onto the given stream."<br>
<br>
+       | type typeIsUnsigned mustCastToUnsigned unsignedType |<br>
+       type := self typeFor: msgNode receiver in: currentMethod.<br>
+       typeIsUnsigned := type first = $u.<br>
+       mustCastToUnsigned := typeIsUnsigned not or:<br>
+               ["cast to usqInt if the int is shorter: we want to avoid UB related to a shift exceeeding bit width"<br>
+               (self sizeOfIntegralCType: type) < (self sizeOfIntegralCType: #usqInt)].<br>
+       "If not unsigned cast it to unsigned."<br>
+       mustCastToUnsigned<br>
-       | type |<br>
-       "If the variable is a 64-bit type then don't cast it to usqInt (typically a 32-bit type)"<br>
-       (self is64BitIntegralVariable: msgNode receiver typeInto: [:t| type := t])<br>
                ifTrue:<br>
+                       ["If the variable is a 64-bit type then don't cast it to usqInt (typically a 32-bit type)"<br>
+                       unsignedType := (self sizeOfIntegralCType: type) < (self sizeOfIntegralCType: #usqLong)<br>
+                               ifTrue: [#usqInt]<br>
+                               ifFalse: [self unsignedTypeForIntegralType: type].<br>
+                        aStream nextPutAll: '(('; nextPutAll: unsignedType; nextPutAll: ')('.<br>
-                       ["If not unsigned cast it to unsigned."<br>
-                        type first ~= $u ifTrue:<br>
-                               [aStream nextPutAll: '((unsigned '; nextPutAll: type; nextPut: $)].<br>
                         self emitCExpression: msgNode receiver on: aStream indent: level.<br>
+                        aStream nextPutAll: '))']<br>
-                        type first ~= $u ifTrue:<br>
-                               [aStream nextPut: $)]]<br>
                ifFalse:<br>
+                       [aStream nextPutAll: '('.<br>
-                       [aStream nextPutAll: '((usqInt) '.<br>
                         self emitCExpression: msgNode receiver on: aStream indent: level.<br>
                         aStream nextPut: $)].<br>
        aStream nextPutAll: ' >> '.<br>
        self emitCExpression: msgNode args first on: aStream indent: level!<br>
<br>
Item was changed:<br>
  ----- Method: CCodeGenerator>>generateSignedBitShift:on:indent: (in category 'C translation') -----<br>
  generateSignedBitShift: msgNode on: aStream indent: level<br>
        "Generate the C code for this message onto the given stream."<br>
<br>
+       | arg shift rightShift |<br>
-       | cast type arg shift |<br>
-       "since ``signed'' is a synonym for ``signed int'' do not cast 64-bit values to signed if at all possible."<br>
-       cast := (self is64BitIntegralVariable: msgNode receiver typeInto: [:t| type := t])<br>
-                               ifTrue: ['(', (type first = $u ifTrue: [type allButFirst: (type second = $n ifTrue: [2] ifFalse: [1])] ifFalse: [type]), ')']<br>
-                               ifFalse: ['(signed)'].<br>
        (self isConstantNode: (arg := msgNode args first) valueInto: [:shiftValue| shift := shiftValue])<br>
                ifTrue: "bit shift amount is a constant"<br>
+                       [aStream nextPut: $(.<br>
-                       [aStream nextPut: $(; nextPutAll: cast.<br>
-                       self emitCExpression: msgNode receiver on: aStream.<br>
                        shift < 0<br>
+                               ifTrue:<br>
+                                       [rightShift := TSendNode new<br>
+                                               setSelector: #>><br>
+                                               receiver: msgNode receiver<br>
+                                               arguments: {TConstantNode new setValue: shift negated}.<br>
+                                       self generateSignedShiftRight: rightShift on: aStream indent: level]<br>
+                               ifFalse: [self generateShiftLeft: msgNode on: aStream indent: level].<br>
-                               ifTrue: [aStream nextPutAll: ' >> '; print: shift negated]<br>
-                               ifFalse: [aStream nextPutAll: ' << '; print: shift].<br>
                        aStream nextPut: $)]<br>
                ifFalse: "bit shift amount is an expression"<br>
+                       [rightShift := TSendNode new<br>
+                                               setSelector: #>><br>
+                                               receiver: msgNode receiver<br>
+                                               arguments: {TSendNode new<br>
+                                                       setSelector: #negated<br>
+                                                       receiver: arg<br>
+                                                       arguments: #()}.<br>
+                       aStream nextPutAll: '(('.<br>
-                       [aStream nextPutAll: '(('.<br>
                        self emitCExpression: arg on: aStream.<br>
+                       aStream nextPutAll: ' < 0) ? ('.<br>
+                       self generateSignedShiftRight: rightShift on: aStream indent: level. <br>
+                       aStream nextPutAll: ') : ('.<br>
+                       self generateShiftLeft: msgNode on: aStream indent: level.<br>
-                       aStream nextPutAll: ' < 0) ? ('; nextPutAll: cast.<br>
-                       self emitCExpression: msgNode receiver on: aStream.<br>
-                       aStream nextPutAll: ' >> -'.<br>
-                       self emitCExpression: arg on: aStream.<br>
-                       aStream nextPutAll: ') : ('; nextPutAll: cast.<br>
-                       self emitCExpression: msgNode receiver on: aStream.<br>
-                       aStream nextPutAll: ' << '.<br>
-                       self emitCExpression: arg on: aStream.<br>
                        aStream nextPutAll: '))']!<br>
<br>
Item was changed:<br>
  ----- Method: CCodeGenerator>>generateSignedShiftRight:on:indent: (in category 'C translation') -----<br>
  generateSignedShiftRight: msgNode on: aStream indent: level<br>
        "Generate the C code for >>> onto the given stream."<br>
<br>
+       | type typeIsUnsigned mustCastToSigned signedType |<br>
+       type := self typeFor: msgNode receiver in: currentMethod.<br>
+       typeIsUnsigned := type first = $u.<br>
+       mustCastToSigned := typeIsUnsigned or:<br>
+               ["cast to sqInt if the int is shorter: we want to avoid UB related to a shift exceeeding bit width"<br>
+               (self sizeOfIntegralCType: type) < (self sizeOfIntegralCType: #usqInt)].<br>
+       mustCastToSigned<br>
-       (self is64BitIntegralVariable: msgNode receiver typeInto: [:t|])<br>
                ifTrue:<br>
+                       ["If the variable is a 64-bit type then don't cast it to usqInt (typically a 32-bit type)"<br>
+                       signedType := (self sizeOfIntegralCType: type) < (self sizeOfIntegralCType: #usqLong)<br>
+                               ifTrue: [#usqInt]<br>
+                               ifFalse: [self signedTypeForIntegralType: type].<br>
+                        aStream nextPutAll: '(('; nextPutAll: signedType; nextPutAll: ')('.<br>
+                        self emitCExpression: msgNode receiver on: aStream indent: level.<br>
+                        aStream nextPutAll: '))']<br>
-                       [aStream nextPutAll: '((sqLong) ']<br>
                ifFalse:<br>
+                       [aStream nextPutAll: '('.<br>
+                        self emitCExpression: msgNode receiver on: aStream indent: level.<br>
+                        aStream nextPut: $)].<br>
+       aStream nextPutAll: ' >> '.<br>
-                       [aStream nextPutAll: '((sqInt) '].<br>
-       self emitCExpression: msgNode receiver on: aStream.<br>
-       aStream nextPutAll: ') >> '.<br>
        self emitCExpression: msgNode args first on: aStream!<br>
<br>
</blockquote></div>