[Vm-dev] VM Maker: VMMaker.oscog-eem.2675.mcz
Nicolas Cellier
nicolas.cellier.aka.nice at gmail.com
Fri Jan 24 21:05:50 UTC 2020
Hi Eliot,
Le ven. 24 janv. 2020 à 01:57, <commits at source.squeak.org> a écrit :
>
> Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
> http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2675.mcz
>
> ==================== Summary ====================
>
> Name: VMMaker.oscog-eem.2675
> Author: eem
> Time: 23 January 2020, 4:57:20.930803 pm
> UUID: ac4a578f-84c7-491c-924d-ca554ddc19a9
> Ancestors: VMMaker.oscog-eem.2674
>
> Cogit: Correct the definition of genPrimitiveHighBit. If there is no
> implementation of LZCNT then it should return UnimplementedPrimitive, not
> CompletedPrimtiive.
>
+1
Reverse the order of operands in ClzR:R:; this is a left-to-right
> assembler, not an ATT syntax right-to-left one.
>
+1, case of brain failure to mimic existing operations...
For some low level ops, it seems I would make an equally bright choice by
flipping a coin ;)
Implement OrCq:R:R: to save an instruction in genPrimitiveHighBit.
> Move genHighBitIn:ofSmallIntegerOopWithSingleTagBit: into the backEnd
> where it belongs.
+1,
it probably ended here at the beginning of my iterations, then code
generation is lax enough so I forgot
it's always a problem to know where to put the slang code (since it does
rarely use receiver)
Nuke the useless genHighBitAlternativeIn:ofSmallIntegerOopWithSingleTagBit:.
>
+/- 1 ?
genHighBitAlternativeIn:ofSmallIntegerOopWithSingleTagBit: was for using
the BSR instruction when there is no LZCNT
Do you mean useless because those µproc are obsolete enough to not bother?
> =============== Diff against VMMaker.oscog-eem.2674 ===============
>
> Item was changed:
> ----- Method: CogARMCompiler>>concretizeClzRR (in category 'generate
> machine code - concretize') -----
> concretizeClzRR
> "Count leading zeros
> First operand is output (dest)
> Second operand is input (mask)"
> "v5 CLZ cond 0001 0110 SBO Rd SBO 0001 Rm
> That is hexa 16rE16FxF1x for cond = AL"
> "v7 CLZ 11111-010-1-011 Rm(4bits) 1111 Rd(4bits) 1000 Rm(4bits)
> That is hexa 16rFABxFx8x"
> <inline: true>
> + | maskReg dest |
> + maskReg := operands at: 0.
> + dest := operands at: 1.
> - | dest mask |
> - dest := operands at: 0.
> - mask := operands at: 1.
> self machineCodeAt: 0 put:
> AL << 28 + 16r16F0F10
> + + (dest << 12) + maskReg.
> - + (dest << 12) + mask.
> ^4!
>
> Item was removed:
> - ----- Method:
> CogAbstractInstruction>>genHighBitAlternativeIn:ofSmallIntegerOopWithSingleTagBit:
> (in category 'abstract instructions') -----
> - genHighBitAlternativeIn: destReg ofSmallIntegerOopWithSingleTagBit:
> srcReg
> - "Use an alternative - if any for generating highBit of
> SmallInteger oop.
> - Default implementation is no-op - there is no universal
> alternative to CLZ.
> - Some target architecture might offer more..."
> - <inline: true>
> - <returnTypeC: #'AbstractInstruction *'>
> - ^0!
>
> Item was changed:
> ----- Method:
> CogAbstractInstruction>>genHighBitClzIn:ofSmallIntegerOopWithSingleTagBit:
> (in category 'abstract instructions') -----
> genHighBitClzIn: destReg ofSmallIntegerOopWithSingleTagBit: srcReg
> "Use CLZ instruction for generating highBit of SmallInteger oop.
> It is sender responsibility to make sure that such CLZ instruction
> is available."
> <inline: true>
> | jumpNegativeReceiver |
> <var: #jumpNegativeReceiver type: #'AbstractInstruction *'>
> + cogit ClzR: srcReg R: destReg.
> - cogit ClzR: destReg R: srcReg.
> (cogit lastOpcode setsConditionCodesFor: JumpZero) ifFalse:
> [cogit CmpCq: 0 R: destReg]. "N.B. FLAGS := destReg - 0"
> jumpNegativeReceiver := cogit JumpZero: 0.
> "Note the nice bit trick below:
> highBit_1based_of_small_int_value = (BytesPerWord * 8) -
> leadingZeroCout_of_oop - 1 toAccountForTagBit.
> This is like 2 complements (- reg - 1) on (BytesPerWord * 8) log2
> bits, or exactly a bit invert operation..."
> cogit XorCw: BytesPerWord * 8 - 1 R: destReg.
> ^jumpNegativeReceiver!
>
> Item was added:
> + ----- Method:
> CogAbstractInstruction>>genHighBitIn:ofSmallIntegerOopWithSingleTagBit: (in
> category 'abstract instructions') -----
> + genHighBitIn: destReg ofSmallIntegerOopWithSingleTagBit: srcReg
> + "Generate code for storing in destReg the 1-based highBit of
> srcReg.
> + Assume that srcReg contains a SmallInteger Oop with a single tag
> bit set to 1.
> + Sender should preprocess Oop when cog representation use
> numSmallIntegerTagBits > 1.
> + Return the jump instruction necessary for handling case of
> negative integer value.
> + Return null pointer if the abstract highBit operation is not
> implemented."
> + <inline: true>
> + self hasLZCNTInstructions ifTrue:
> + [^self genHighBitClzIn: destReg
> ofSmallIntegerOopWithSingleTagBit: srcReg].
> + ^0!
>
> Item was changed:
> ----- Method: CogIA32Compiler>>concretizeClzRR (in category 'generate
> machine code - concretize') -----
> concretizeClzRR
> "Count leading zeros
> First operand is output (dest)
> Second operand is input (mask)"
> "LZCNT"
> <inline: true>
> + | maskReg dest |
> + maskReg := operands at: 0.
> + dest := operands at: 1.
> - | dest mask |
> - dest := operands at: 0.
> - mask := operands at: 1.
> machineCode
> at: 0 put: 16rF3;
> at: 1 put: 16r0F;
> at: 2 put: 16rBD;
> + at: 3 put: (self mod: ModReg RM: dest RO: maskReg).
> - at: 3 put: (self mod: ModReg RM: dest RO: mask).
> ^4!
>
> Item was changed:
> ----- Method: CogMIPSELCompiler>>computeMaximumSize (in category
> 'generate machine code') -----
> computeMaximumSize
> "Each MIPS instruction has 4 bytes. Many abstract opcodes need
> more than one
> instruction. Instructions that refer to constants and/or literals
> depend on literals
> being stored in-line or out-of-line.
>
> N.B. The ^N forms are to get around the bytecode compiler's long
> branch
> limits which are exceeded when each case jumps around the
> otherwise."
>
> opcode
> caseOf: {
> [BrEqualRR] ->
> [^8].
> [BrNotEqualRR] -> [^8].
> [BrUnsignedLessRR] -> [^12].
> [BrUnsignedLessEqualRR] -> [^12].
> [BrUnsignedGreaterRR] -> [^12].
> [BrUnsignedGreaterEqualRR] -> [^12].
> [BrSignedLessRR] -> [^12].
> [BrSignedLessEqualRR] -> [^12].
> [BrSignedGreaterRR] -> [^12].
> [BrSignedGreaterEqualRR] -> [^12].
> [BrLongEqualRR] -> [^16].
> [BrLongNotEqualRR] -> [^16].
> [MulRR] -> [^4].
> [DivRR] -> [^4].
> [MoveLowR] -> [^4].
> [MoveHighR] -> [^4].
>
> "Noops & Pseudo Ops"
> [Label] -> [^0].
> [Literal] -> [^4].
> [AlignmentNops] -> [^(operands at: 0) - 4].
> [Fill32] -> [^4].
> [Nop] -> [^4].
> "Control"
> [Call] -> [^self
> literalLoadInstructionBytes + 8].
> [CallFull] -> [^self
> literalLoadInstructionBytes + 8].
> [JumpR] -> [^8].
> [Jump] -> [^8].
> [JumpFull] -> [^self
> literalLoadInstructionBytes + 8].
> [JumpLong] -> [^self
> literalLoadInstructionBytes + 8].
> [JumpZero] -> [^8].
> [JumpNonZero] -> [^8].
> [JumpNegative] -> [^8].
> [JumpNonNegative] -> [^8].
> [JumpOverflow] -> [^8].
> [JumpNoOverflow] -> [^8].
> [JumpCarry] -> [^8].
> [JumpNoCarry] -> [^8].
> [JumpLess] -> [^8].
> [JumpGreaterOrEqual] -> [^8].
> [JumpGreater] -> [^8].
> [JumpLessOrEqual] -> [^8].
> [JumpBelow] -> [^8].
> [JumpAboveOrEqual] -> [^8].
> [JumpAbove] -> [^8].
> [JumpBelowOrEqual] -> [^8].
> [JumpLongZero] -> [^self
> literalLoadInstructionBytes + 8].
> [JumpLongNonZero] -> [^self
> literalLoadInstructionBytes + 8].
> [JumpFPEqual] -> [^8].
> [JumpFPNotEqual] -> [^8].
> [JumpFPLess] -> [^8].
> [JumpFPGreaterOrEqual]-> [^8].
> [JumpFPGreater] -> [^8].
> [JumpFPLessOrEqual] -> [^8].
> [JumpFPOrdered] -> [^8].
> [JumpFPUnordered] -> [^8].
> [RetN] -> [^8].
> [Stop] -> [^4].
>
> "Arithmetic"
> [AddCqR] -> [^12].
> [AndCqR] -> [^16].
> + [OrCqR] -> [^16].
> [AndCqRR] -> [^12].
> [CmpCqR] -> [^28].
> [OrCqR] -> [^12].
> [SubCqR] -> [^12].
> [TstCqR] -> [^12].
> [XorCqR] -> [^12].
> [AddCwR] -> [^12].
> [AndCwR] -> [^12].
> [CmpCwR] -> [^28].
> [OrCwR] -> [^12].
> [SubCwR] -> [^12].
> [XorCwR] -> [^12].
> [AddRR] -> [^4].
> [AndRR] -> [^4].
> [CmpRR] -> [^20].
> [OrRR] -> [^4].
> [XorRR] -> [^4].
> [SubRR] -> [^4].
> [NegateR] -> [^4].
> [LoadEffectiveAddressMwrR] -> [^12].
> [LogicalShiftLeftCqR] -> [^4].
> [LogicalShiftRightCqR] -> [^4].
> [ArithmeticShiftRightCqR] -> [^4].
> [LogicalShiftLeftRR] -> [^4].
> [LogicalShiftRightRR] -> [^4].
> [ArithmeticShiftRightRR] -> [^4].
> [AddRdRd] -> [^4].
> [CmpRdRd] -> [^4].
> [SubRdRd] -> [^4].
> [MulRdRd] -> [^4].
> [DivRdRd] -> [^4].
> [SqrtRd] -> [^4].
> [AddCheckOverflowCqR] -> [^28].
> [AddCheckOverflowRR] -> [^20].
> [SubCheckOverflowCqR] -> [^28].
> [SubCheckOverflowRR] -> [^20].
> [MulCheckOverflowRR] -> [^20].
> [ClzRR] -> [^4].
> "Data Movement"
> [MoveCqR] -> [^8 "or 4"].
> [MoveCwR] -> [^8].
> [MoveRR] -> [^4].
> [MoveRdRd] -> [^4].
> [MoveAwR] -> [^(self
> isAddressRelativeToVarBase: (operands at: 0))
>
> ifTrue: [4]
>
> ifFalse: [self literalLoadInstructionBytes +
> 4]].
> [MoveRAw] -> [^(self
> isAddressRelativeToVarBase: (operands at: 1))
>
> ifTrue: [4]
>
> ifFalse: [self literalLoadInstructionBytes +
> 4]].
> [MoveAbR] -> [^(self
> isAddressRelativeToVarBase: (operands at: 0))
>
> ifTrue: [4]
>
> ifFalse: [self literalLoadInstructionBytes +
> 4]].
> [MoveRAb] -> [^(self
> isAddressRelativeToVarBase: (operands at: 1))
>
> ifTrue: [4]
>
> ifFalse: [self literalLoadInstructionBytes +
> 4]].
> [MoveRMwr] -> [^16].
> [MoveRdM64r] -> [^self
> literalLoadInstructionBytes + 4].
> [MoveMbrR] -> [^4].
> [MoveRMbr] -> [^4].
> [MoveM16rR] -> [^4].
> [MoveRM16r] -> [^4].
> [MoveM64rRd] -> [^self
> literalLoadInstructionBytes + 4].
> [MoveMwrR] -> [^16].
> [MoveXbrRR] -> [^8].
> [MoveRXbrR] -> [^8].
> [MoveXwrRR] -> [^12].
> [MoveRXwrR] -> [^12].
> [PopR] -> [^8].
> [PushR] -> [^8].
> [PushCw] -> [^16].
> [PushCq] -> [^16].
> [PrefetchAw] -> [^12].
> "Conversion"
> [ConvertRRd] -> [^8].
> }.
> ^0 "to keep C compiler quiet"
> !
>
> Item was changed:
> ----- Method: CogMIPSELCompiler>>concretizeClzRR (in category 'generate
> machine code - concretize') -----
> concretizeClzRR
> + | maskReg destReg rightReg |
> + maskReg := operands at: 0.
> + destReg := rightReg := operands at: 1.
> + self machineCodeAt: 0 put: (self clzR: destReg R: maskReg R:
> rightReg).
> - | destReg leftReg rightReg |
> - destReg := rightReg := operands at: 0.
> - leftReg := operands at: 1.
> - self machineCodeAt: 0 put: (self clzR: destReg R: leftReg R:
> rightReg).
> ^4!
>
> Item was added:
> + ----- Method: CogMIPSELCompiler>>concretizeOrCqRR (in category 'generate
> machine code - concretize') -----
> + concretizeOrCqRR
> + | value srcReg dstReg |
> + value := operands at: 0.
> + srcReg := operands at: 1.
> + dstReg := operands at: 2.
> + self machineCodeAt: 0 put: (self luiR: AT C: (self high16BitsOf:
> value)).
> + self machineCodeAt: 4 put: (self oriR: AT R: AT C: (self
> low16BitsOf: value)).
> + self machineCodeAt: 8 put: (self orR: dstReg R: srcReg R: AT).
> + ^12!
>
> Item was changed:
> ----- Method: CogMIPSELCompiler>>dispatchConcretize (in category
> 'generate machine code') -----
> dispatchConcretize
> "Attempt to generate concrete machine code for the instruction at
> address.
> This is the inner dispatch of concretizeAt: actualAddress which
> exists only
> to get around the branch size limits in the SqueakV3 (blue book
> derived)
> bytecode set."
> opcode caseOf: {
> [BrEqualRR] ->
> [^self concretizeBrEqualRR].
> [BrNotEqualRR] -> [^self
> concretizeBrNotEqualRR].
> [BrUnsignedLessRR] -> [^self
> concretizeBrUnsignedLessRR].
> [BrUnsignedLessEqualRR] -> [^self
> concretizeBrUnsignedLessEqualRR].
> [BrUnsignedGreaterRR] -> [^self
> concretizeBrUnsignedGreaterRR].
> [BrUnsignedGreaterEqualRR] -> [^self
> concretizeBrUnsignedGreaterEqualRR].
> [BrSignedLessRR] -> [^self
> concretizeBrSignedLessRR].
> [BrSignedLessEqualRR] -> [^self
> concretizeBrSignedLessEqualRR].
> [BrSignedGreaterRR] -> [^self
> concretizeBrSignedGreaterRR].
> [BrSignedGreaterEqualRR] -> [^self
> concretizeBrSignedGreaterEqualRR].
> [BrLongEqualRR] -> [^self
> concretizeBrLongEqualRR].
> [BrLongNotEqualRR] -> [^self
> concretizeBrLongNotEqualRR].
> [MulRR] -> [^self
> concretizeUnimplemented].
> [DivRR] -> [^self concretizeDivRR].
> [MoveLowR] -> [^self concretizeMoveLowR].
> [MoveHighR] -> [^self concretizeMoveHighR].
>
>
> "Noops & Pseudo Ops"
> [Label] -> [^self
> concretizeLabel].
> [AlignmentNops] -> [^self concretizeAlignmentNops].
> [Fill32] -> [^self
> concretizeFill32].
> [Nop] -> [^self
> concretizeNop].
> "Control"
> [Call] -> [^self
> concretizeCall]. "call code within code space"
> [CallFull] -> [^self
> concretizeCallFull]. "call code anywhere in address space"
> [JumpR] -> [^self
> concretizeJumpR].
> [JumpFull] -> [^self
> concretizeJumpFull]."jump within address space"
> [JumpLong] -> [^self
> concretizeJumpLong]."jumps witihn code space"
> [JumpLongZero] -> [^self
> concretizeJumpLongZero].
> [JumpLongNonZero] -> [^self
> concretizeJumpLongNonZero].
> [Jump] -> [^self
> concretizeJump].
> [JumpZero] -> [^self
> concretizeJumpZero].
> [JumpNonZero] -> [^self
> concretizeJumpNonZero].
> [JumpNegative] -> [^self
> concretizeUnimplemented].
> [JumpNonNegative] -> [^self
> concretizeUnimplemented].
> [JumpOverflow] -> [^self
> concretizeJumpOverflow].
> [JumpNoOverflow] -> [^self
> concretizeJumpNoOverflow].
> [JumpCarry] -> [^self
> concretizeUnimplemented].
> [JumpNoCarry] -> [^self
> concretizeUnimplemented].
> [JumpLess] -> [^self
> concretizeJumpSignedLessThan].
> [JumpGreaterOrEqual] -> [^self
> concretizeJumpSignedGreaterEqual].
> [JumpGreater] -> [^self
> concretizeJumpSignedGreaterThan].
> [JumpLessOrEqual] -> [^self
> concretizeJumpSignedLessEqual].
> [JumpBelow] -> [^self
> concretizeJumpUnsignedLessThan].
> [JumpAboveOrEqual] -> [^self
> concretizeJumpUnsignedGreaterEqual].
> [JumpAbove] -> [^self
> concretizeJumpUnsignedGreaterThan].
> [JumpBelowOrEqual] -> [^self
> concretizeJumpUnsignedLessEqual].
> [JumpFPEqual] -> [^self
> concretizeUnimplemented].
> [JumpFPNotEqual] -> [^self
> concretizeUnimplemented].
> [JumpFPLess] -> [^self
> concretizeUnimplemented].
> [JumpFPGreaterOrEqual] -> [^self concretizeUnimplemented].
> [JumpFPGreater] -> [^self
> concretizeUnimplemented].
> [JumpFPLessOrEqual] -> [^self
> concretizeUnimplemented].
> [JumpFPOrdered] -> [^self
> concretizeUnimplemented].
> [JumpFPUnordered] -> [^self
> concretizeUnimplemented].
> [RetN] -> [^self
> concretizeRetN].
> [Stop] -> [^self
> concretizeStop].
> "Arithmetic"
> [AddCqR] -> [^self
> concretizeAddCqR].
> [AndCqR] -> [^self
> concretizeAndCqR].
> [AndCqRR] -> [^self
> concretizeAndCqRR].
> + [AndCqRR] -> [^self
> concretizeOrCqRR].
> [CmpCqR] -> [^self
> concretizeCmpCqR].
> + [OrCqR] -> [^self
> concretizeOrCqR].
> - [OrCqR] -> [^self
> concretizeOrCqR].
> [SubCqR] -> [^self
> concretizeSubCqR].
> [TstCqR] -> [^self
> concretizeTstCqR].
> [XorCqR] -> [^self
> concretizeUnimplemented].
> [AddCwR] -> [^self
> concretizeAddCwR].
> [AndCwR] -> [^self
> concretizeAndCwR].
> [CmpCwR] -> [^self
> concretizeCmpCwR].
> [OrCwR] -> [^self
> concretizeOrCwR].
> [SubCwR] -> [^self
> concretizeSubCwR].
> [XorCwR] -> [^self
> concretizeXorCwR].
> [AddRR] -> [^self
> concretizeAddRR].
> [AndRR] -> [^self
> concretizeAndRR].
> [CmpRR] -> [^self
> concretizeCmpRR].
> [OrRR] -> [^self
> concretizeOrRR].
> [SubRR] -> [^self
> concretizeSubRR].
> [XorRR] -> [^self
> concretizeXorRR].
> [AddRdRd] -> [^self
> concretizeUnimplemented].
> [CmpRdRd] -> [^self
> concretizeUnimplemented].
> [DivRdRd] -> [^self
> concretizeUnimplemented].
> [MulRdRd] -> [^self
> concretizeUnimplemented].
> [SubRdRd] -> [^self
> concretizeUnimplemented].
> [SqrtRd] -> [^self
> concretizeUnimplemented].
> [NegateR] ->
> [^self concretizeNegateR].
> [LoadEffectiveAddressMwrR] -> [^self
> concretizeLoadEffectiveAddressMwrR].
> [ArithmeticShiftRightCqR] -> [^self
> concretizeArithmeticShiftRightCqR].
> [LogicalShiftRightCqR] -> [^self
> concretizeLogicalShiftRightCqR].
> [LogicalShiftLeftCqR] -> [^self
> concretizeLogicalShiftLeftCqR].
> [ArithmeticShiftRightRR] -> [^self
> concretizeArithmeticShiftRightRR].
> [LogicalShiftLeftRR] -> [^self
> concretizeLogicalShiftLeftRR].
> [LogicalShiftRightRR] -> [^self
> concretizeLogicalShiftRightRR].
> [ClzRR] -> [^self
> concretizeClzRR].
> "Data Movement"
> [MoveCqR] -> [^self
> concretizeMoveCqR].
> [MoveCwR] -> [^self
> concretizeMoveCwR].
> [MoveRR] -> [^self
> concretizeMoveRR].
> [MoveAwR] -> [^self
> concretizeMoveAwR].
> [MoveRAw] -> [^self
> concretizeMoveRAw].
> [MoveAbR] -> [^self
> concretizeMoveAbR].
> [MoveRAb] -> [^self
> concretizeMoveRAb].
> [MoveMbrR] -> [^self
> concretizeMoveMbrR].
> [MoveRMbr] -> [^self
> concretizeUnimplemented].
> [MoveM16rR] -> [^self concretizeMoveM16rR].
> [MoveRM16r] -> [^self concretizeMoveRM16r].
> [MoveM64rRd] -> [^self concretizeUnimplemented].
> [MoveMwrR] -> [^self concretizeMoveMwrR].
> [MoveXbrRR] -> [^self concretizeMoveXbrRR].
> [MoveRXbrR] -> [^self concretizeMoveRXbrR].
> [MoveXwrRR] -> [^self concretizeMoveXwrRR].
> [MoveRXwrR] -> [^self concretizeMoveRXwrR].
> [MoveRMwr] -> [^self concretizeMoveRMwr].
> [MoveRdM64r] -> [^self concretizeUnimplemented].
> [PopR] -> [^self concretizePopR].
> [PushR] -> [^self concretizePushR].
> [PushCq] -> [^self
> concretizePushCq].
> [PushCw] -> [^self
> concretizePushCw].
> [PrefetchAw] -> [^self concretizePrefetchAw].
> [AddCheckOverflowCqR] -> [^self
> concretizeAddCheckOverflowCqR].
> [AddCheckOverflowRR] -> [^self
> concretizeAddCheckOverflowRR].
> [SubCheckOverflowCqR] -> [^self
> concretizeSubCheckOverflowCqR].
> [SubCheckOverflowRR] -> [^self
> concretizeSubCheckOverflowRR].
> [MulCheckOverflowRR] -> [^self
> concretizeMulCheckOverflowRR].
> "Conversion"
> [ConvertRRd] -> [^self
> concretizeUnimplemented]}.
>
> ^0 "keep Slang happy"!
>
> Item was changed:
> ----- Method: CogMIPSELCompiler>>noteFollowingConditionalBranch: (in
> category 'abstract instructions') -----
> noteFollowingConditionalBranch: branch
> "Support for processors without condition codes, such as the MIPS.
> Answer the branch opcode. Modify the receiver and the branch to
> implement a suitable conditional branch that doesn't depend on
> condition codes being set by the receiver."
> <returnTypeC: #'AbstractInstruction *'>
> <var: #branch type: #'AbstractInstruction *'>
> | newBranchLeft newBranchOpcode newBranchRight |
>
> ((branch opcode = JumpOverflow) or: [branch opcode =
> JumpNoOverflow])
> ifTrue: [^self noteFollowingOverflowBranch: branch].
>
> newBranchOpcode := branch opcode caseOf: {
> [JumpZero] -> [BrEqualRR].
> [JumpNonZero] -> [BrNotEqualRR].
> [JumpBelow] -> [BrUnsignedLessRR].
> [JumpBelowOrEqual] -> [BrUnsignedLessEqualRR].
> [JumpAbove] -> [BrUnsignedGreaterRR].
> [JumpAboveOrEqual] -> [BrUnsignedGreaterEqualRR].
> [JumpLess] ->
> [BrSignedLessRR].
> [JumpLessOrEqual] -> [BrSignedLessEqualRR].
> [JumpGreater] -> [BrSignedGreaterRR].
> [JumpGreaterOrEqual] -> [BrSignedGreaterEqualRR].
> [JumpLongZero] -> [BrLongEqualRR].
> [JumpLongNonZero] -> [BrLongNotEqualRR].
>
> [JumpNegative] -> [BrSignedLessRR].
> } otherwise: [self unreachable. 0].
>
> opcode caseOf: {
> [BrEqualRR] -> ["I.e., two jumps after a compare."
> newBranchLeft := operands
> at: 1.
> newBranchRight := operands
> at: 2].
> [BrUnsignedLessRR] -> ["I.e., two jumps after a
> compare."
> newBranchLeft := operands
> at: 1.
> newBranchRight := operands
> at: 2].
>
> [CmpRR] -> [newBranchLeft := operands at: 1.
> newBranchRight :=
> operands at: 0.
> opcode := Label].
> [CmpCqR] -> [newBranchLeft := operands at: 1.
> newBranchRight := AT.
> opcode := MoveCqR.
> operands at: 1 put: AT].
> [CmpCwR] -> [newBranchLeft := operands at: 1.
> newBranchRight := AT.
> opcode := MoveCwR.
> operands at: 1 put: AT].
> [TstCqR] -> [newBranchLeft := Cmp.
> newBranchRight := ZR].
> [AndCqR] -> [newBranchLeft := operands at: 1.
> newBranchRight := ZR].
> [AndCqRR] -> [newBranchLeft := operands at: 2.
> newBranchRight := ZR].
> + [OrCqRR] -> [newBranchLeft := operands at: 2.
> + newBranchRight := ZR].
> [OrRR] -> [newBranchLeft := operands at: 1.
> newBranchRight := ZR].
> [XorRR] -> [newBranchLeft := operands at: 1.
> newBranchRight := ZR].
> [SubCwR] -> [newBranchLeft := operands at: 1.
> newBranchRight := ZR].
> [SubCqR] -> [newBranchLeft := operands at: 1.
> newBranchRight := ZR].
> [ArithmeticShiftRightCqR] -> [newBranchLeft :=
> operands at: 1.
> newBranchRight := ZR].
> [ClzRR] -> [newBranchLeft := operands at: 0. "we test
> if the destination register is zero"
> newBranchRight := ZR].
> } otherwise: [self unreachable].
>
> branch rewriteOpcode: newBranchOpcode with: newBranchLeft with:
> newBranchRight.
> ^branch!
>
> Item was changed:
> ----- Method: CogObjectRepresentation>>genPrimitiveHighBit (in category
> 'primitive generators') -----
> genPrimitiveHighBit
> "Implementation notes: there are two reasons to use TempReg
> -1) if primitive fails, ReceiverResultReg must remain unchanged
> (we CompletePrimitive)
> -2) CLZ/BSR only work on 64bits for registers R0-R7 on Intel X64.
> But Win64 uses R9
> Normally, this should be backEnd dependent, but for now we have a
> single 64bits target..."
>
> | jumpNegativeReceiver |
> <var: #jumpNegativeReceiver type: #'AbstractInstruction *'>
> "remove excess tag bits from the receiver oop"
> - cogit MoveR: ReceiverResultReg R: TempReg.
> self numSmallIntegerTagBits > 1
> ifTrue:
> + [cogit OrCq: 1 << self numSmallIntegerTagBits - 1
> R: ReceiverResultReg R: TempReg.
> + cogit ArithmeticShiftRightCq: self
> numSmallIntegerTagBits - 1 R: TempReg.
> + jumpNegativeReceiver := cogit backEnd
> genHighBitIn: TempReg ofSmallIntegerOopWithSingleTagBit: TempReg]
> - [cogit OrCq: 1 << self numSmallIntegerTagBits - 1
> R: TempReg.
> - cogit ArithmeticShiftRightCq: self
> numSmallIntegerTagBits - 1 R: TempReg].
> - "and use the abstract cogit facility for case of single tag-bit"
> - jumpNegativeReceiver := cogit genHighBitIn: TempReg
> ofSmallIntegerOopWithSingleTagBit: TempReg.
> - "Jump is NULL if above operation is not implemented, else return
> the result"
> - jumpNegativeReceiver = 0
> ifFalse:
> + ["and use the abstract cogit facility for case of
> single tag-bit"
> + jumpNegativeReceiver := cogit backEnd
> genHighBitIn: TempReg ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg].
> +
> + "Jump is NULL if above operation is not implemented, else return
> the result"
> + jumpNegativeReceiver = 0 ifTrue:
> + [^UnimplementedPrimitive].
> +
> + cogit MoveR: TempReg R: ReceiverResultReg.
> + self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
> + cogit genPrimReturn.
> + jumpNegativeReceiver jmpTarget: cogit Label.
> - [cogit MoveR: TempReg R: ReceiverResultReg.
> - cogit genConvertIntegerToSmallIntegerInReg:
> ReceiverResultReg.
> - cogit genPrimReturn.
> - jumpNegativeReceiver jmpTarget: cogit Label].
> ^CompletePrimitive!
>
> Item was changed:
> ----- Method: CogOutOfLineLiteralsARMCompiler>>usesOutOfLineLiteral (in
> category 'testing') -----
> usesOutOfLineLiteral
> "Answer if the receiver uses an out-of-line literal. Needs only
> to work for the opcodes created with gen:literal:operand: et al."
>
> opcode
> caseOf: {
> [CallFull] -> [^true].
> [JumpFull] -> [^true].
> "Arithmetic"
> [AddCqR] -> [^self
> rotateable8bitSignedImmediate: (operands at: 0) ifTrue: [:r :i :n| false]
> ifFalse: [true]].
> [AddCqRR] -> [^self
> rotateable8bitSignedImmediate: (operands at: 0) ifTrue: [:r :i :n| false]
> ifFalse: [true]].
> [AndCqR] -> [^self
> rotateable8bitBitwiseImmediate: (operands at: 0)
> ifTrue:
> [:r :i :n| false]
> ifFalse:
> [1 << (operands at: 0) highBit ~= ((operands at: 0) + 1)]].
> [AndCqRR] -> [^self
> rotateable8bitBitwiseImmediate: (operands at: 0)
> ifTrue:
> [:r :i :n| false]
> ifFalse:
> [1 << (operands at: 0) highBit ~= ((operands at: 0) + 1)]].
> + [OrCqRR] -> [^self
> rotateable8bitBitwiseImmediate: (operands at: 0)
> + ifTrue:
> [:r :i :n| false]
> + ifFalse:
> [1 << (operands at: 0) highBit ~= ((operands at: 0) + 1)]].
> [CmpCqR] -> [^self
> rotateable8bitSignedImmediate: (operands at: 0) ifTrue: [:r :i :n| false]
> ifFalse: [true]].
> [OrCqR] -> [^self rotateable8bitImmediate:
> (operands at: 0) ifTrue: [:r :i| false] ifFalse: [true]].
> [SubCqR] -> [^self
> rotateable8bitSignedImmediate: (operands at: 0) ifTrue: [:r :i :n| false]
> ifFalse: [true]].
> [TstCqR] -> [^self rotateable8bitImmediate:
> (operands at: 0) ifTrue: [:r :i| false] ifFalse: [true]].
> [XorCqR] -> [^self
> rotateable8bitBitwiseImmediate: (operands at: 0) ifTrue: [:r :i :n| false]
> ifFalse: [true]].
> [AddCwR] -> [^true].
> [AndCwR] -> [^true].
> [CmpCwR] -> [^true].
> [OrCwR] -> [^true].
> [SubCwR] -> [^true].
> [XorCwR] -> [^true].
> [LoadEffectiveAddressMwrR]
> -> [^self
> rotateable8bitImmediate: (operands at: 0) ifTrue: [:r :i| false] ifFalse:
> [true]].
> "Data Movement"
> [MoveCqR] -> [^self rotateable8bitImmediate:
> (operands at: 0) ifTrue: [:r :i| false] ifFalse: [true]].
> [MoveCwR] -> [^(self inCurrentCompilation:
> (operands at: 0)) not].
> [MoveAwR] -> [^(self
> isAddressRelativeToVarBase: (operands at: 0)) ifTrue: [false] ifFalse:
> [true]].
> [MoveRAw] -> [^(self
> isAddressRelativeToVarBase: (operands at: 1)) ifTrue: [false] ifFalse:
> [true]].
> [MoveAbR] -> [^(self
> isAddressRelativeToVarBase: (operands at: 0)) ifTrue: [false] ifFalse:
> [true]].
> [MoveRAb] -> [^(self
> isAddressRelativeToVarBase: (operands at: 1)) ifTrue: [false] ifFalse:
> [true]].
> [MoveRMwr] -> [^self is12BitValue: (operands at: 1)
> ifTrue: [:u :i| false] ifFalse: [true]].
> [MoveRdM64r] -> [^self is12BitValue: (operands at: 1)
> ifTrue: [:u :i| false] ifFalse: [true]].
> [MoveMbrR] -> [^self is12BitValue: (operands
> at: 0) ifTrue: [:u :i| false] ifFalse: [true]].
> [MoveRMbr] -> [^self is12BitValue: (operands
> at: 1) ifTrue: [:u :i| false] ifFalse: [true]].
> [MoveM16rR] -> [^self rotateable8bitImmediate:
> (operands at: 0) ifTrue: [:r :i| false] ifFalse: [true]].
> [MoveRM16r] -> [^self is12BitValue: (operands at: 1)
> ifTrue: [:u :i| false] ifFalse: [true]].
> [MoveM64rRd] -> [^self is12BitValue: (operands at: 0)
> ifTrue: [:u :i| false] ifFalse: [true]].
> [MoveMwrR] -> [^self is12BitValue: (operands at: 0)
> ifTrue: [:u :i| false] ifFalse: [true]].
> [PushCw] -> [^(self inCurrentCompilation:
> (operands at: 0)) not].
> [PushCq] -> [^self rotateable8bitImmediate:
> (operands at: 0) ifTrue: [:r :i| false] ifFalse: [true]].
> [PrefetchAw] -> [^(self isAddressRelativeToVarBase:
> (operands at: 0)) ifTrue: [false] ifFalse: [true]].
> }
> otherwise: [self assert: false].
> ^false "to keep C compiler quiet"
> !
>
> Item was changed:
> SharedPool subclass: #CogRTLOpcodes
> instanceVariableNames: ''
> + classVariableNames: 'AddCqR AddCqRR AddCwR AddRR AddRRR AddRdRd
> AddRsRs AddcCqR AddcRR AlignmentNops AndCqR AndCqRR AndCwR AndRR
> ArithmeticShiftRightCqR ArithmeticShiftRightCqRR ArithmeticShiftRightRR
> Call CallFull CallR ClzRR CmpC32R CmpCqR CmpCwR CmpRR CmpRdRd CmpRsRs
> ConvertRRd ConvertRRs ConvertRdR ConvertRdRs ConvertRsR ConvertRsRd DivRdRd
> DivRsRs Fill32 FirstJump FirstShortJump Jump JumpAbove JumpAboveOrEqual
> JumpBelow JumpBelowOrEqual JumpCarry JumpFPEqual JumpFPGreater
> JumpFPGreaterOrEqual JumpFPLess JumpFPLessOrEqual JumpFPNotEqual
> JumpFPOrdered JumpFPUnordered JumpFull JumpGreater JumpGreaterOrEqual
> JumpLess JumpLessOrEqual JumpLong JumpLongNonZero JumpLongZero JumpNegative
> JumpNoCarry JumpNoOverflow JumpNonNegative JumpNonZero JumpOverflow JumpR
> JumpZero Label LastJump LastRTLCode Literal LoadEffectiveAddressMwrR
> LogicalShiftLeftCqR LogicalShiftLeftCqRR LogicalShiftLeftRR
> LogicalShiftRightCqR LogicalShiftRightCqRR LogicalShiftRightRR MoveA32R
> MoveAbR MoveAwR MoveC32R Mo
> veCqR MoveCwR MoveM16rR MoveM32rR MoveM32rRs MoveM64rRd MoveM8rR MoveMbrR
> MoveMs8rR MoveMwrR MoveRA32 MoveRAb MoveRAw MoveRM16r MoveRM32r MoveRM8r
> MoveRMbr MoveRMwr MoveRR MoveRRd MoveRX16rR MoveRX32rR MoveRXbrR MoveRXwrR
> MoveRdM64r MoveRdR MoveRdRd MoveRsM32r MoveRsRs MoveX16rRR MoveX32rRR
> MoveXbrRR MoveXwrRR MulRdRd MulRsRs NegateR Nop NotR OrCqR OrCqRR OrCwR
> OrRR PopR PrefetchAw PushCq PushCw PushR RetN RotateLeftCqR RotateRightCqR
> SignExtend16RR SignExtend32RR SignExtend8RR SqrtRd SqrtRs Stop SubCqR
> SubCwR SubRR SubRRR SubRdRd SubRsRs SubbCqR SubbRR TstCqR XorCqR XorCwR
> XorRR XorRdRd XorRsRs ZeroExtend16RR ZeroExtend32RR ZeroExtend8RR'
> - classVariableNames: 'AddCqR AddCqRR AddCwR AddRR AddRRR AddRdRd
> AddRsRs AddcCqR AddcRR AlignmentNops AndCqR AndCqRR AndCwR AndRR
> ArithmeticShiftRightCqR ArithmeticShiftRightCqRR ArithmeticShiftRightRR
> Call CallFull CallR ClzRR CmpC32R CmpCqR CmpCwR CmpRR CmpRdRd CmpRsRs
> ConvertRRd ConvertRRs ConvertRdR ConvertRdRs ConvertRsR ConvertRsRd DivRdRd
> DivRsRs Fill32 FirstJump FirstShortJump Jump JumpAbove JumpAboveOrEqual
> JumpBelow JumpBelowOrEqual JumpCarry JumpFPEqual JumpFPGreater
> JumpFPGreaterOrEqual JumpFPLess JumpFPLessOrEqual JumpFPNotEqual
> JumpFPOrdered JumpFPUnordered JumpFull JumpGreater JumpGreaterOrEqual
> JumpLess JumpLessOrEqual JumpLong JumpLongNonZero JumpLongZero JumpNegative
> JumpNoCarry JumpNoOverflow JumpNonNegative JumpNonZero JumpOverflow JumpR
> JumpZero Label LastJump LastRTLCode Literal LoadEffectiveAddressMwrR
> LogicalShiftLeftCqR LogicalShiftLeftCqRR LogicalShiftLeftRR
> LogicalShiftRightCqR LogicalShiftRightCqRR LogicalShiftRightRR MoveA32R
> MoveAbR MoveAwR MoveC32R Mo
> veCqR MoveCwR MoveM16rR MoveM32rR MoveM32rRs MoveM64rRd MoveM8rR MoveMbrR
> MoveMs8rR MoveMwrR MoveRA32 MoveRAb MoveRAw MoveRM16r MoveRM32r MoveRM8r
> MoveRMbr MoveRMwr MoveRR MoveRRd MoveRX16rR MoveRX32rR MoveRXbrR MoveRXwrR
> MoveRdM64r MoveRdR MoveRdRd MoveRsM32r MoveRsRs MoveX16rRR MoveX32rRR
> MoveXbrRR MoveXwrRR MulRdRd MulRsRs NegateR Nop NotR OrCqR OrCwR OrRR PopR
> PrefetchAw PushCq PushCw PushR RetN RotateLeftCqR RotateRightCqR
> SignExtend16RR SignExtend32RR SignExtend8RR SqrtRd SqrtRs Stop SubCqR
> SubCwR SubRR SubRRR SubRdRd SubRsRs SubbCqR SubbRR TstCqR XorCqR XorCwR
> XorRR XorRdRd XorRsRs ZeroExtend16RR ZeroExtend32RR ZeroExtend8RR'
> poolDictionaries: ''
> category: 'VMMaker-JIT'!
>
> !CogRTLOpcodes commentStamp: 'eem 12/26/2015 14:00' prior: 0!
> I am a pool for the Register-Transfer-Language to which Cog compiles. I
> define unique integer values for all RTL opcodes. See
> CogAbstractInstruction for instances of instructions with the opcodes that
> I define.!
>
> Item was changed:
> ----- Method: CogRTLOpcodes class>>initialize (in category 'class
> initialization') -----
> (excessive size, no diff calculated)
>
> Item was changed:
> ----- Method: CogX64Compiler>>concretizeClzRR (in category 'generate
> machine code - concretize') -----
> concretizeClzRR
> "Count leading zeros
> First operand is output (dest)
> Second operand is input (mask)"
>
Maybe update the comment:
left operand is input (mask), right operand is output (dest)
"LZCNT"
> <inline: true>
> + | maskReg dest |
> + maskReg := operands at: 0.
> + dest := operands at: 1.
> - | dest mask |
> - dest := operands at: 0.
> - mask := operands at: 1.
> machineCode
> + at: 0 put: 16rF3;
> + at: 1 put: (self rexw: true r: 0 x: 0 b: 0);
>
Does this mean that it's sender responsibility to provide registers <= 7?
- at: 0 put: 16rF3.
> - (dest <= 7 and: [mask <= 7])
> - ifTrue: [machineCode at: 1 put: (self rexw: true r: 0 x: 0
> b: 0)]
> - ifFalse: [machineCode at: 1 put: (self rexw: false r: 0 x:
> 0 b: 0)].
> -
> - machineCode
> at: 2 put: 16r0F;
> at: 3 put: 16rBD;
> + at: 4 put: (self mod: ModReg RM: dest RO: maskReg).
> - at: 4 put: (self mod: ModReg RM: dest RO: mask).
> ^5!
>
> Item was changed:
> ----- Method: Cogit>>ClzR:R: (in category 'abstract instructions') -----
> ClzR: reg1 R: reg2
+ "reg2 := reg1 countLeadingZeros"
>
and maybe rename parameters as maskReg (or srcReg) and destReg like
OrCqR:R: below...
> <inline: true>
> <returnTypeC: #'AbstractInstruction *'>
> ^self gen: ClzRR operand: reg1 operand: reg2!
>
> Item was added:
> + ----- Method: Cogit>>OrCq:R:R: (in category 'abstract instructions')
> -----
> + OrCq: quickConstant R: srcReg R: destReg
> + <inline: false>
> + <returnTypeC: #'AbstractInstruction *'>
> + | first |
> + backEnd hasThreeAddressArithmetic ifTrue:
> + [^self gen: OrCqRR quickConstant: quickConstant operand:
> srcReg operand: destReg].
> + srcReg = destReg ifTrue:
> + [^self gen: OrCqR quickConstant: quickConstant operand:
> destReg].
> + first := self gen: MoveRR operand: srcReg operand: destReg.
> + self gen: OrCqR quickConstant: quickConstant operand: destReg.
> + ^first!
>
> Item was removed:
> - ----- Method: Cogit>>genHighBitIn:ofSmallIntegerOopWithSingleTagBit: (in
> category 'abstract instructions') -----
> - genHighBitIn: destReg ofSmallIntegerOopWithSingleTagBit: srcReg
> - "Generate code for storing in destReg the 1-based highBit of
> srcReg.
> - Assume that srcReg contains a SmallInteger Oop with a single tag
> bit set to 1.
> - Sender should preprocess Oop when cog representation use
> numSmallIntegerTagBits > 1.
> - Return the jump instruction necessary for handling case of
> negative integer value.
> - Return null pointer if the abstract highBit operation is not
> implemented.
> -
> - The implementation depends on availability of instructions on the
> target architecture,
> - so delegate to the backend."
> - <inline: true>
> - <returnTypeC: #'AbstractInstruction *'>
> - backEnd hasLZCNTInstructions
> - ifTrue: [^self genHighBitClzIn: destReg
> ofSmallIntegerOopWithSingleTagBit: srcReg]
> - ifFalse: [^self genHighBitAlternativeIn: destReg
> ofSmallIntegerOopWithSingleTagBit: srcReg]!
>
> Item was added:
> + ----- Method: CurrentImageCoInterpreterFacade>>highBit: (in category
> 'cog jit support') -----
> + highBit: anInteger
> + ^anInteger highBit!
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20200124/07fb0842/attachment-0001.html>
More information about the Vm-dev
mailing list