[Vm-dev] VM Maker: VMMaker.oscog-eem.1234.mcz

Eliot Miranda eliot.miranda at gmail.com
Wed Apr 22 02:41:01 UTC 2015


Oops.  Didn't mean to upload that twice.  No harm done I hope.

On Tue, Apr 21, 2015 at 7:38 PM, <commits at source.squeak.org> wrote:

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


-- 
best,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20150421/1f39efbc/attachment-0001.htm


More information about the Vm-dev mailing list