<div dir="ltr">Oops. Didn't mean to upload that twice. No harm done I hope.</div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Apr 21, 2015 at 7:38 PM, <span dir="ltr"><<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>></span> wrote:<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.1234.mcz" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1234.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-eem.1234<br>
Author: eem<br>
Time: 21 April 2015, 6:52:37.482 pm<br>
UUID: 012b3371-995e-451f-85ec-a5144379427d<br>
Ancestors: VMMaker.oscog-tpr.1233<br>
<br>
Cogit:<br>
Allow ARM concretizeMoveCwR use pc-relative<br>
addressing alongside PushCwR. Fix the effects on<br>
PIC parsing by introducing loadPICLiteralByteSize.<br>
<br>
Correct slip in sub:rn:imm:ror:.<br>
Fix sub:rn:imm:ror:.<br>
Fix relocateMethodReferenceBeforeAddress:by:<br>
for the 4 cases we have now.<br>
<br>
Code compaction now works once again on ARM<br>
but we generate more compact code and most<br>
method/pic self-references are made with non-<br>
relocateable pc-relative addressing. Woot!<br>
<br>
=============== Diff against VMMaker.oscog-tpr.1233 ===============<br>
<br>
Item was changed:<br>
----- Method: CogARMCompiler>>concretizeMoveCwR (in category 'generate machine code - concretize') -----<br>
concretizeMoveCwR<br>
"Will get inlined into concretizeAt: switch."<br>
<inline: true><br>
+ ^machineCodeSize := self loadCwInto: (self concreteRegister: (operands at: 1))!<br>
- | constant destReg |<br>
- constant := operands at: 0.<br>
- destReg := self concreteRegister: (operands at: 1).<br>
- ^machineCodeSize :=self at: 0 moveCw: constant intoR: destReg!<br>
<br>
Item was changed:<br>
----- Method: CogARMCompiler>>concretizePushCw (in category 'generate machine code - concretize') -----<br>
concretizePushCw<br>
"Will get inlined into concretizeAt: switch."<br>
<inline: true><br>
+ | instrOffset |<br>
+ instrOffset := self loadCwInto: ConcreteIPReg.<br>
- | operand instrOffset distance |<br>
- operand := operands at: 0.<br>
- instrOffset := 0.<br>
- "First try and encode as a pc-relative reference..."<br>
- (cogit addressIsInCodeZone: operand) ifTrue:<br>
- [distance := operand - (address + 8).<br>
- self rotateable8bitImmediate: distance<br>
- ifTrue: [ :rot :immediate |<br>
- self machineCodeAt: 0 put: (self add: ConcreteIPReg rn: PC imm: immediate ror: rot).<br>
- instrOffset := 4]<br>
- ifFalse:<br>
- [self rotateable8bitImmediate: distance negated<br>
- ifTrue: [ :rot :immediate |<br>
- self machineCodeAt: 0 put: (self sub: ConcreteIPReg rn: PC imm: immediate ror: rot).<br>
- instrOffset := 4]<br>
- ifFalse: [instrOffset := 0]]].<br>
- "If this fails, use the conventional and painfully long 4 instruction sequence."<br>
- instrOffset = 0 ifTrue:<br>
- [instrOffset := self at: 0 moveCw: operand intoR: ConcreteIPReg].<br>
self machineCodeAt: instrOffset put: (self pushR: ConcreteIPReg).<br>
^machineCodeSize := instrOffset + 4!<br>
<br>
Item was added:<br>
+ ----- Method: CogARMCompiler>>instructionIsPush: (in category 'testing') -----<br>
+ instructionIsPush: instr<br>
+ "is this a push -str r??, [sp, #-4] - instruction?"<br>
+ ^instr >> 28 < 16rF "test for allowed condcode - 0xF is extension"<br>
+ and: [(instr bitAnd: 16rFFF0FFF) = 16r52D0004]!<br>
<br>
Item was added:<br>
+ ----- Method: CogARMCompiler>>loadCwInto: (in category 'generate machine code - support') -----<br>
+ loadCwInto: destReg<br>
+ "Load the operand into the destination register, answering<br>
+ the size of the instructions generated to do so."<br>
+ | operand distance |<br>
+ operand := operands at: 0.<br>
+ "First try and encode as a pc-relative reference..."<br>
+ (cogit addressIsInCodeZone: operand) ifTrue:<br>
+ [distance := operand - (address + 8).<br>
+ self rotateable8bitImmediate: distance<br>
+ ifTrue: [ :rot :immediate |<br>
+ self machineCodeAt: 0 put: (self add: destReg rn: PC imm: immediate ror: rot).<br>
+ ^4]<br>
+ ifFalse:<br>
+ [self rotateable8bitImmediate: distance negated<br>
+ ifTrue: [ :rot :immediate |<br>
+ self machineCodeAt: 0 put: (self sub: destReg rn: PC imm: immediate ror: rot).<br>
+ ^4]<br>
+ ifFalse: []]].<br>
+ "If this fails, use the conventional and painfully long 4 instruction sequence."<br>
+ ^self at: 0 moveCw: operand intoR: destReg!<br>
<br>
Item was added:<br>
+ ----- Method: CogARMCompiler>>loadPICLiteralByteSize (in category 'accessing') -----<br>
+ loadPICLiteralByteSize<br>
+ "Answer the byte size of a MoveCwR opcode's corresponding machine code<br>
+ when the argument is a PIC. This is for the self-reference at the end of a<br>
+ closed PIC. On ARM this is a single instruction pc-relative register load."<br>
+ ^4!<br>
<br>
Item was removed:<br>
- ----- Method: CogARMCompiler>>movePCRelative:into: (in category 'generate machine code - support') -----<br>
- movePCRelative: operand into: reg<br>
- "Load a pc relative value into the register"<br>
- | offset sign instr |<br>
- offset := operand - (address + 8).<br>
- sign := offset >= 0 ifTrue: [1] ifFalse: [0].<br>
- instr := self ldr: reg rn: PC plus: sign imm: offset abs.<br>
- self machineCodeAt: 0 put: instr.<br>
- ^4!<br>
<br>
Item was changed:<br>
----- Method: CogARMCompiler>>relocateMethodReferenceBeforeAddress:by: (in category 'inline cacheing') -----<br>
relocateMethodReferenceBeforeAddress: pc by: delta<br>
"If possible we generate the method address using pc-relative addressing.<br>
If so we don't need to relocate it in code. So check if pc-relative code was<br>
+ generated, and if not, adjust a long sequence. There are two cases, a push<br>
+ or a register load. If a push, then there is a register load, but in the instruction<br>
+ before."<br>
+ | pcPreceedingLoad reference |<br>
+ pcPreceedingLoad := (self instructionIsPush: (self instructionBeforeAddress: pc))<br>
+ ifTrue: [pc - 4]<br>
+ ifFalse: [pc].<br>
+ "If the load is not done via pc-relative addressing we have to relocate."<br>
+ (self isPCRelativeValueLoad: (self instructionBeforeAddress: pcPreceedingLoad)) ifFalse:<br>
+ [reference := self extract32BitOperandFrom4InstructionsPreceeding: pcPreceedingLoad.<br>
+ reference := reference + delta.<br>
+ self insert32BitOperand: reference into4InstructionsPreceeding: pcPreceedingLoad]!<br>
- generated, and if not, adjust a long sequence."<br>
- | location |<br>
- (self isPCRelativeValueLoad: (self instructionBeforeAddress: pc - 4)) ifFalse:<br>
- [location := self extract32BitOperandFrom4InstructionsPreceeding: pc - 4.<br>
- location := location + delta.<br>
- self insert32BitOperand: location into4InstructionsPreceeding: pc - 4]!<br>
<br>
Item was changed:<br>
----- Method: CogARMCompiler>>sub:rn:imm:ror: (in category 'ARM convenience instructions') -----<br>
sub: destReg rn: srcReg imm: immediate ror: rot<br>
" Remember the ROR is doubled by the cpu so use 30>>1 etc<br>
SUB destReg, srcReg, #immediate ROR rot"<br>
<br>
+ ^self type: 1 op: SubOpcode set: 0 rn: srcReg rd: destReg shifterOperand: ((rot>>1) <<8 bitOr: immediate)!<br>
- ^self type: 1 op: 2 set: 0 rn: srcReg rd: destReg shifterOperand: ((rot>>1) <<8 bitOr: immediate)!<br>
<br>
Item was changed:<br>
----- Method: CogAbstractInstruction>>isPCRelativeValueLoad: (in category 'testing') -----<br>
isPCRelativeValueLoad: instr<br>
+ <var: 'instr' type: #'unsigned int'><br>
+ "add xx, pc, blah or sub xx, pc, blah"<br>
+ ^(instr >> 16) = 16rE28F or: [instr >> 16 = 16rE24F]!<br>
- "add ip, pc, blah-> '16rE28FC000'<br>
- sub ip, pc, blah -> '16rE24FC000'"<br>
- ^(instr bitAnd: 16rFFFFF000) = 16rE28FC000<br>
- or: [(instr bitAnd: 16rFFFFF000) = 16rE24FC000]!<br>
<br>
Item was added:<br>
+ ----- Method: CogAbstractInstruction>>loadPICLiteralByteSize (in category 'accessing') -----<br>
+ loadPICLiteralByteSize<br>
+ "Answer the byte size of a MoveCwR opcode's corresponding machine code<br>
+ when the argument is a PIC. This is for the self-reference at the end of a<br>
+ closed PIC."<br>
+ self subclassResponsibility!<br>
<br>
Item was added:<br>
+ ----- Method: CogIA32Compiler>>loadPICLiteralByteSize (in category 'accessing') -----<br>
+ loadPICLiteralByteSize<br>
+ "Answer the byte size of a MoveCwR opcode's corresponding machine code<br>
+ when the argument is a PIC. This is for the self-reference at the end of a<br>
+ closed PIC."<br>
+ <inline: true><br>
+ ^self loadLiteralByteSize!<br>
<br>
Item was changed:<br>
----- Method: Cogit>>addressIsInCodeZone: (in category 'testing') -----<br>
addressIsInCodeZone: address<br>
"N.B. We /don't/ write this as address between: codeBase and: methodZone limitZony in case we're<br>
testing an address in a method whose code has yet to be allocated and is hence >= methodZone limitZony"<br>
^address asUnsignedInteger >= codeBase<br>
+ and: [address < (methodZone youngReferrers ifNil: [0])]!<br>
- and: [address < methodZone youngReferrers]!<br>
<br>
Item was changed:<br>
----- Method: Cogit>>compileClosedPICPrototype (in category 'in-line cacheing') -----<br>
compileClosedPICPrototype<br>
"Compile the abstract instructions for a full closed PIC used to initialize closedPICSize.<br>
The loads into SendNumArgsReg are those for optional method objects which may be<br>
used in MNU cases."<br>
| numArgs jumpNext |<br>
<var: #jumpNext type: #'AbstractInstruction *'><br>
numArgs := 0.<br>
self compilePICAbort: numArgs.<br>
jumpNext := self compileCPICEntry.<br>
self MoveCw: 16r5EAF00D R: SendNumArgsReg.<br>
self JumpLong: methodZoneBase + 16rCA5E10.<br>
jumpNext jmpTarget: (endCPICCase0 := self Label).<br>
1 to: numPICCases - 1 do:<br>
[:h|<br>
self CmpCw: 16rBABE1F15+h R: TempReg.<br>
self MoveCw: 16rBADA550 + h R: SendNumArgsReg.<br>
self JumpLongZero: 16rCA5E10 + (h * 16).<br>
h = 1 ifTrue:<br>
[endCPICCase1 := self Label]].<br>
+ self MoveCw: methodZoneBase R: ClassReg.<br>
- self MoveCw: 16rAB5CE55 R: ClassReg.<br>
self JumpLong: (self cPICMissTrampolineFor: numArgs).<br>
^0!<br>
<br>
Item was changed:<br>
----- Method: Cogit>>relocateCallsInClosedPIC: (in category 'compaction') -----<br>
relocateCallsInClosedPIC: cPIC<br>
<var: #cPIC type: #'CogMethod *'><br>
| delta pc entryPoint targetMethod |<br>
<var: #targetMethod type: #'CogMethod *'><br>
delta := cPIC objectHeader.<br>
self assert: (backEnd callTargetFromReturnAddress: cPIC asInteger + missOffset)<br>
= (self picAbortTrampolineFor: cPIC cmNumArgs).<br>
backEnd relocateCallBeforeReturnPC: cPIC asInteger + missOffset by: delta negated.<br>
<br>
pc := cPIC asInteger + firstCPICCaseOffset.<br>
1 to: cPIC cPICNumCases do:<br>
[:i|<br>
entryPoint := backEnd jumpLongTargetBeforeFollowingAddress: pc.<br>
"Find target from jump. Ignore jumps to the interpret and MNU calls within this PIC"<br>
(entryPoint < cPIC asInteger<br>
or: [entryPoint > (cPIC asInteger + cPIC blockSize)]) ifTrue:<br>
[targetMethod := self cCoerceSimple: entryPoint - cmNoCheckEntryOffset to: #'CogMethod *'.<br>
self assert: targetMethod cmType = CMMethod.<br>
backEnd<br>
relocateJumpLongBeforeFollowingAddress: pc<br>
by: (delta - targetMethod objectHeader) negated].<br>
pc := pc + cPICCaseSize].<br>
self assert: cPIC cPICNumCases > 0.<br>
pc := pc - cPICCaseSize.<br>
"Finally relocate the load of the PIC and the jump to the overflow routine ceCPICMiss:receiver:"<br>
+ backEnd relocateMethodReferenceBeforeAddress: pc + backEnd loadPICLiteralByteSize by: delta.<br>
- backEnd relocateMethodReferenceBeforeAddress: pc + backEnd loadLiteralByteSize by: delta.<br>
backEnd relocateJumpLongBeforeFollowingAddress: pc + cPICEndSize by: delta negated!<br>
<br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">best,<div>Eliot</div></div>
</div>