<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>Hi Nicolas,</div><div><br>On Mar 20, 2015, at 1:32 PM, Nicolas Cellier <<a href="mailto:nicolas.cellier.aka.nice@gmail.com">nicolas.cellier.aka.nice@gmail.com</a>> wrote:<br><br></div><blockquote type="cite"><div><span></span></div></blockquote><blockquote type="cite"><div><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2015-03-20 0:21 GMT+01:00 <span dir="ltr"><<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:<br>
<a href="http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1103.mcz" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1103.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-eem.1103<br>
Author: eem<br>
Time: 19 March 2015, 4:20:02.926 pm<br>
UUID: 64ddd2e1-e5f5-4ad0-b512-b1d0e32e99f7<br>
Ancestors: VMMaker.oscog-eem.1102<br>
<br>
Fix some Slang issues with ARM methods (clashing<br>
arg names).<br>
<br>
Provide an abstraction for saving & restoring link reg<br>
around calls.<br>
<br>
=============== Diff against VMMaker.oscog-eem.1102 ===============<br>
<br>
Item was changed:<br>
----- Method: CoInterpreter>>ceTraceLinkedSend: (in category 'debug support') -----<br>
ceTraceLinkedSend: theReceiver<br>
| cogMethod |<br>
<api><br>
<var: #cogMethod type: #'CogMethod *'><br>
cogMethod := self cCoerceSimple: (self stackTop - cogit traceLinkedSendOffset)<br>
to: #'CogMethod *'.<br>
self cCode: [] inSmalltalk:<br>
[cogit checkStackDepthOnSend ifTrue:<br>
[self maybeCheckStackDepth: (cogMethod cmNumArgs > cogit numRegArgs<br>
ifTrue: [cogMethod cmNumArgs + 1]<br>
ifFalse: [0])<br>
sp: stackPointer + objectMemory wordSize<br>
pc: (self stackValue: 1)]].<br>
"cogit recordSendTrace ifTrue: is implicit; wouldn't compile the call otherwise."<br>
self recordTrace: (objectMemory fetchClassOf: theReceiver)<br>
thing: cogMethod selector<br>
source: TraceIsFromMachineCode.<br>
cogit printOnTrace ifTrue:<br>
[self printActivationNameFor: cogMethod methodObject<br>
receiver: theReceiver<br>
isBlock: false<br>
+ firstTemporary: (self cCode: [nil] inSmalltalk: [0]);<br>
- firstTemporary: nil;<br>
cr].<br>
self sendBreakpoint: cogMethod selector receiver: theReceiver!<br>
<br>
Item was changed:<br>
----- Method: CogARMCompiler>>concretizeDataOperationCqR: (in category 'generate machine code - concretize') -----<br>
+ concretizeDataOperationCqR: armOpcode<br>
- concretizeDataOperationCqR: opcode<br>
"Will get inlined into concretizeAt: switch."<br>
"4 == Add, 2 == Sub, Xor == 1, And == 0, Or == 12, Bic == 14"<br>
<inline: true><br>
self<br>
rotateable8bitImmediate: (operands at: 0)<br>
ifTrue: [:rot :immediate | | rd rn |<br>
rn := self concreteRegister: (operands at: 1).<br>
rd := opcode = CmpOpcode ifTrue: [0] ifFalse:[rn].<br>
+ self machineCodeAt: 0 put: (self type: 1 op: armOpcode set: 1 rn: rn rd: rd shifterOperand: ((rot>>1)"in this usage we have to halve the rot value" << 8 bitOr: immediate)).<br>
- self machineCodeAt: 0 put: (self type: 1 op: opcode set: 1 rn: rn rd: rd shifterOperand: ((rot>>1)"in this usage we have to halve the rot value" << 8 bitOr: immediate)).<br>
^machineCodeSize := 4]<br>
+ ifFalse: [^self concretizeDataOperationCwR: armOpcode].<br>
- ifFalse: [^self concretizeDataOperationCwR: opcode].<br>
!<br>
<br>
Item was changed:<br>
----- Method: CogARMCompiler>>concretizeDataOperationCwR: (in category 'generate machine code - concretize') -----<br>
+ concretizeDataOperationCwR: armOpcode<br>
- concretizeDataOperationCwR: opcode<br>
"Will get inlined into concretizeAt: switch."<br>
"Load the word into the RISCTempReg, then cmp R, RISCTempReg"<br>
<inline: true><br>
| constant rn rd instrOffset|<br>
constant := operands at: 0.<br>
rn := (self concreteRegister: (operands at: 1)).<br>
+ rd := armOpcode = CmpOpcode ifTrue: [0] ifFalse:[rn].<br>
- rd := opcode = CmpOpcode ifTrue: [0] ifFalse:[rn].<br>
instrOffset := self at: 0 moveCw: constant intoR: RISCTempReg.<br>
self machineCodeAt: instrOffset<br>
+ put: (self type: 0 op: armOpcode set: 1 rn: rn rd: rd shifterOperand: RISCTempReg).<br>
- put: (self type: 0 op: opcode set: 1 rn: rn rd: rd shifterOperand: RISCTempReg).<br>
^machineCodeSize := instrOffset + 4!<br>
<br>
Item was changed:<br>
----- Method: CogARMCompiler>>concretizeDataOperationRR: (in category 'generate machine code - concretize') -----<br>
+ concretizeDataOperationRR: armOpcode<br>
- concretizeDataOperationRR: opcode<br>
"Will get inlined into concretizeAt: switch."<br>
"Load the word into the RISCTempReg, then op R, RISCTempReg"<br>
<inline: true><br>
| rn rd srcReg |<br>
srcReg := self concreteRegister: (operands at: 0).<br>
rn := (self concreteRegister: (operands at: 1)).<br>
+ rd := armOpcode = CmpOpcode ifTrue: [0] ifFalse: [rn].<br>
- rd := opcode = CmpOpcode ifTrue: [0] ifFalse: [rn].<br>
self machineCodeAt: 0<br>
+ put: (self type: 0 op: armOpcode set: 1 rn: rn rd: rd shifterOperand: srcReg).<br>
- put: (self type: 0 op: opcode set: 1 rn: rn rd: rd shifterOperand: srcReg).<br>
^machineCodeSize := 4.!<br>
<br>
Item was changed:<br>
----- Method: CogARMCompiler>>extractOffsetFromBXAt: (in category 'testing') -----<br>
+ extractOffsetFromBXAt: addr<br>
- extractOffsetFromBXAt: address<br>
"this should return the long call/jump target"<br>
+ ^(objectMemory byteAt: addr -4)<br>
+ + ((objectMemory byteAt: addr - 8) << 8)<br>
+ + ((objectMemory byteAt: addr - 12) << 16)<br>
+ + ((objectMemory byteAt: addr - 16) << 24)!<br>
- ^(objectMemory byteAt: address -4)<br>
- + ((objectMemory byteAt: address - 8) << 8)<br>
- + ((objectMemory byteAt: address - 12) << 16)<br>
- + ((objectMemory byteAt: address - 16) << 24)!<br>
<br>
Item was added:<br>
+ ----- Method: CogARMCompiler>>saveAndRestoreLinkRegAround: (in category 'abi') -----<br>
+ saveAndRestoreLinkRegAround: aBlock<br>
+ "If the processor's ABI includes a link register, generate instructions<br>
+ to save and restore it around aBlock, which is assumed to generate code."<br>
+ <inline: true><br>
+ | inst |<br>
+ inst := cogit PushR: LinkReg.<br>
+ aBlock value.<br>
+ cogit PopR: LinkReg.<br>
+ ^inst!<br>
<br>
Item was added:<br>
+ ----- Method: CogAbstractInstruction>>saveAndRestoreLinkRegAround: (in category 'abi') -----<br>
+ saveAndRestoreLinkRegAround: aBlock<br>
+ "If the processor's ABI includes a link register, generate instructions<br>
+ to save and restore it around aBlock, which is assumed to generate code."<br>
+ <inline: true><br>
+ self subclassResponsibility!<br>
<br>
Item was added:<br>
+ ----- Method: CogIA32Compiler>>saveAndRestoreLinkRegAround: (in category 'abi') -----<br>
+ saveAndRestoreLinkRegAround: aBlock<br>
+ "If the processor's ABI includes a link register, generate instructions<br>
+ to save and restore it around aBlock, which is assumed to generate code."<br>
+ <inline: true><br>
+ ^aBlock value!<br>
<br></blockquote><div><br></div><div>Hmm, the generater doesn't know how to deal with this one...<br></div><div>It tries to inline the formal parameter (block) rather than the actual block passed by the sender.<br></div></div></div></div></div></blockquote><div><br></div>Hmm... R u sure? I tried this in a workspace I use for slang testing and saw no problem.<div><br><blockquote type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>Nicolas<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Item was changed:<br>
----- Method: Cogit>>compileEntry (in category 'compile abstract instructions') -----<br>
compileEntry<br>
"The entry code to a method checks that the class of the current receiver matches<br>
that in the inline cache. Other non-obvious elements are that its alignment must be<br>
different from the alignment of the noCheckEntry so that the method map machinery<br>
can distinguish normal and super sends (super sends bind to the noCheckEntry).<br>
In Newspeak we also need to distinguish dynSuperSends from normal and super<br>
and so on Nespeak, bind the dynSuperEntry to the preceeding nop (on x86 there<br>
happens to be one anyway)."<br>
<br>
self cppIf: NewspeakVM ifTrue:<br>
[self Nop. "1st nop differentiates dynSuperEntry from no-check entry if using nextMethod"<br>
dynSuperEntry := self Nop].<br>
entry := objectRepresentation genGetInlineCacheClassTagFrom: ReceiverResultReg into: TempReg forEntry: true.<br>
self CmpR: ClassReg R: TempReg.<br>
self JumpNonZero: sendMiss.<br>
noCheckEntry := self Label.<br>
self compileSendTrace ifTrue:<br>
+ [backEnd saveAndRestoreLinkRegAround:<br>
+ [self CallRT: ceTraceLinkedSendTrampoline]]!<br>
- [backEnd hasLinkRegister ifTrue:<br>
- [self PushR: LinkReg].<br>
- self CallRT: ceTraceLinkedSendTrampoline.<br>
- backEnd hasLinkRegister ifTrue:<br>
- [self PopR: LinkReg]]!<br>
<br>
Item was changed:<br>
----- Method: StackToRegisterMappingCogit>>genFramelessStorePop:ReceiverVariable: (in category 'bytecode generators') -----<br>
genFramelessStorePop: popBoolean ReceiverVariable: slotIndex<br>
<inline: false><br>
| topReg valueReg constVal |<br>
self assert: needsFrame not.<br>
self ssFlushUpThroughReceiverVariable: slotIndex.<br>
"Avoid store check for immediate values"<br>
constVal := self ssTop maybeConstant.<br>
(self ssTop type = SSConstant<br>
and: [(objectRepresentation shouldAnnotateObjectReference: constVal) not]) ifTrue:<br>
[self ensureReceiverResultRegContainsSelf.<br>
self ssStorePop: popBoolean toPreferredReg: TempReg.<br>
traceStores > 0 ifTrue:<br>
+ [backEnd saveAndRestoreLinkRegAround:<br>
+ [self CallRT: ceTraceStoreTrampoline]].<br>
- [self CallRT: ceTraceStoreTrampoline].<br>
^objectRepresentation<br>
genStoreImmediateInSourceReg: TempReg<br>
slotIndex: slotIndex<br>
destReg: ReceiverResultReg].<br>
(topReg := self ssTop registerOrNil) isNil ifTrue:<br>
[topReg := ClassReg].<br>
valueReg := self ssStorePop: popBoolean toPreferredReg: topReg.<br>
"Note that ReceiverResultReg remains live after ceStoreCheckTrampoline."<br>
self ensureReceiverResultRegContainsSelf.<br>
traceStores > 0 ifTrue:<br>
[self MoveR: valueReg R: TempReg.<br>
+ backEnd saveAndRestoreLinkRegAround:<br>
+ [self CallRT: ceTraceStoreTrampoline]].<br>
- self CallRT: ceTraceStoreTrampoline].<br>
^objectRepresentation<br>
genStoreSourceReg: valueReg<br>
slotIndex: slotIndex<br>
destReg: ReceiverResultReg<br>
scratchReg: TempReg!<br>
<br>
</blockquote></div><br></div></div>
</div></blockquote></div></body></html>