[Vm-dev] VM Maker: VMMaker.oscog-eem.2297.mcz
Eliot Miranda
eliot.miranda at gmail.com
Thu Dec 21 01:52:11 UTC 2017
Hi Bleeding Edgers,
I f'ed up in the below, breaking at: for DoubleWordArray. The fix is
not immediately obvious, so beware.
On Wed, Dec 20, 2017 at 3:19 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.2297.mcz
>
> ==================== Summary ====================
>
> Name: VMMaker.oscog-eem.2297
> Author: eem
> Time: 20 December 2017, 3:18:42.905102 pm
> UUID: ed1f68f5-33bc-459c-b954-afc70c35b8a4
> Ancestors: VMMaker.oscog-eem.2296
>
> Cogit: Extend Spur 64-bit primitiveAt with full support for 64-bit longs.
>
> Fix some typos and comment out unused C64 & Xowr opcodes.
>
> =============== Diff against VMMaker.oscog-eem.2296 ===============
>
> Item was added:
> + ----- Method: CogObjectRepresentationFor64BitSpur>>
> genAlloc64BitIntegerValue:into:scratchReg:scratchReg: (in category
> 'primitive generators') -----
> + genAlloc64BitIntegerValue: valueReg into: resultReg scratchReg: scratch1
> scratchReg: scratch2
> + <returnTypeC: #'AbstractInstruction *'>
> + | allocSize newLPIHeader jumpFail |
> + <var: #jumpFail type: #'AbstractInstruction *'>
> + allocSize := objectMemory baseHeaderSize + objectMemory wordSize.
> + newLPIHeader := objectMemory
> + headerForSlots: 1
> + format:
> objectMemory firstByteFormat
> + classIndex:
> ClassLargePositiveIntegerCompactIndex.
> + cogit MoveAw: objectMemory freeStartAddress R: resultReg.
> + cogit LoadEffectiveAddressMw: allocSize r: resultReg R: scratch1.
> + cogit CmpCq: objectMemory getScavengeThreshold R: scratch1.
> + jumpFail := cogit JumpAboveOrEqual: 0.
> + cogit MoveR: scratch1 Aw: objectMemory freeStartAddress.
> + self genStoreHeader: newLPIHeader intoNewInstance: resultReg
> using: scratch1.
> + cogit MoveR: valueReg M64: objectMemory baseHeaderSize r:
> resultReg.
> + ^jumpFail!
>
> Item was changed:
> ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveAt (in
> category 'primitive generators') -----
> genPrimitiveAt
> | formatReg nSlotsOrBytesReg convertToIntAndReturn methodInBounds
> jumpNotIndexable jumpImmediate jumpBadIndex
> + jumpIsBytes jumpIsShorts jumpIsWords jumpIsLongs jumpIsMethod
> jumpIsArray jumpIsContext
> - jumpIsBytes jumpIsShorts jumpIsWords jumpIsMethod jumpIsArray
> jumpIsContext
> jumpHasFixedFields jumpArrayOutOfBounds
> jumpFixedFieldsOutOfBounds
> + jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds
> jumpLongsOutOfBounds
> + jumpFailAlloc jumpNotSmallInteger |
> - jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds |
> "c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format:
> fixedFieldsOf:format:length:"
> <var: #jumpIsBytes type: #'AbstractInstruction *'>
> + <var: #jumpIsLongs type: #'AbstractInstruction *'>
> + <var: #jumpFailAlloc type: #'AbstractInstruction *'>
> <var: #jumpIsShorts type: #'AbstractInstruction *'>
> - <var: #jumpBadIndex type: #'AbstractInstruction *'>
> <var: #jumpIsMethod type: #'AbstractInstruction *'>
> + <var: #jumpBadIndex type: #'AbstractInstruction *'>
> <var: #jumpIsContext type: #'AbstractInstruction *'>
> <var: #jumpImmediate type: #'AbstractInstruction *'>
> <var: #methodInBounds type: #'AbstractInstruction *'>
> <var: #jumpNotIndexable type: #'AbstractInstruction *'>
> <var: #jumpHasFixedFields type: #'AbstractInstruction *'>
> + <var: #jumpNotSmallInteger type: #'AbstractInstruction *'>
> <var: #convertToIntAndReturn type: #'AbstractInstruction *'>
> <var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
> <var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
> + <var: #jumpLongsOutOfBounds type: #'AbstractInstruction *'>
> <var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
> <var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
> <var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'>
>
> nSlotsOrBytesReg := ClassReg.
>
> cogit genLoadArgAtDepth: 0 into: Arg0Reg.
> jumpImmediate := self genJumpImmediate: ReceiverResultReg.
> cogit MoveR: Arg0Reg R: Arg1Reg.
> jumpBadIndex := self genJumpNotSmallInteger: Arg0Reg scratchReg:
> TempReg.
> self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
> cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"
>
> "formatReg := self formatOf: ReceiverResultReg"
> self genGetFormatOf: ReceiverResultReg
> into: (formatReg := SendNumArgsReg)
> leastSignificantHalfOfBaseHeaderIntoScratch: TempReg.
>
> self genGetNumSlotsOf: ReceiverResultReg into: nSlotsOrBytesReg.
>
> "dispatch on format in a combination of highest dynamic frequency
> order first and convenience.
> 0 = 0 sized objects (UndefinedObject True False et al)
> 1 = non-indexable objects with inst vars (Point et al)
> 2 = indexable objects with no inst vars (Array et al)
> 3 = indexable objects with inst vars (MethodContext
> AdditionalMethodState et al)
> 4 = weak indexable objects with inst vars (WeakArray et
> al)
> 5 = weak non-indexable objects with inst vars
> (ephemerons) (Ephemeron)
> 6 unused, reserved for exotic pointer objects?
> 7 Forwarded Object, 1st field is pointer, rest of fields
> are ignored
> 8 unused, reserved for exotic non-pointer objects?
> 9 64-bit indexable
> 10 - 11 32-bit indexable
> 12 - 15 16-bit indexable
> 16 - 23 byte indexable
> 24 - 31 compiled method"
> cogit CmpCq: objectMemory firstByteFormat R: formatReg.
> jumpIsBytes := cogit JumpAboveOrEqual: 0.
> cogit CmpCq: objectMemory
> arrayFormat R: formatReg.
> jumpIsArray := cogit JumpZero: 0.
> jumpNotIndexable := cogit JumpBelow: 0.
> cogit CmpCq: objectMemory
> weakArrayFormat R: formatReg.
> jumpHasFixedFields := cogit JumpBelowOrEqual: 0.
> cogit CmpCq: objectMemory
> firstShortFormat R: formatReg.
> jumpIsShorts := cogit JumpAboveOrEqual: 0.
> cogit CmpCq: objectMemory
> firstLongFormat R: formatReg.
> jumpIsWords := cogit JumpAboveOrEqual: 0.
> + cogit CmpCq: objectMemory
> sixtyFourBitIndexableFormat R: formatReg.
> + jumpIsLongs := cogit JumpZero: 0.
> - "For now ignore 64-bit indexability."
> jumpNotIndexable jmpTarget: cogit Label.
> jumpNotIndexable := cogit Jump: 0.
>
> jumpIsArray jmpTarget:
> (cogit CmpR: Arg1Reg R: nSlotsOrBytesReg).
> jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.
> cogit AddCq: objectMemory baseHeaderSize >> objectMemory
> shiftForWord R: Arg1Reg.
> cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
> cogit genPrimReturn.
>
> jumpIsBytes jmpTarget:
> (cogit LogicalShiftLeftCq: objectMemory shiftForWord R:
> nSlotsOrBytesReg).
> cogit AndCq: objectMemory wordSize - 1 R: formatReg R:
> TempReg.
> cogit SubR: TempReg R: nSlotsOrBytesReg;
> CmpR: Arg1Reg R: nSlotsOrBytesReg.
> jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
> cogit CmpCq: objectMemory firstCompiledMethodFormat R: formatReg.
> jumpIsMethod := cogit JumpAboveOrEqual: 0.
> methodInBounds :=
> (cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg).
> cogit backEnd byteReadsZeroExtend
> ifTrue:
> [cogit MoveXbr: Arg1Reg R: ReceiverResultReg R:
> ReceiverResultReg]
> ifFalse:
> [cogit "formatReg already contains a value <=
> 16r1f, so no need to zero it"
> MoveXbr: Arg1Reg R: ReceiverResultReg R:
> formatReg;
> MoveR: formatReg R: ReceiverResultReg].
> convertToIntAndReturn := cogit Label.
> self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
> cogit genPrimReturn.
>
> jumpIsShorts jmpTarget:
> (cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1
> R: nSlotsOrBytesReg).
> cogit AndCq: 1 R: formatReg.
> cogit SubR: formatReg R: nSlotsOrBytesReg;
> CmpR: Arg1Reg R: nSlotsOrBytesReg.
> jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
> cogit AddR: Arg1Reg R: ReceiverResultReg.
> cogit AddR: Arg1Reg R: ReceiverResultReg.
> cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R:
> ReceiverResultReg.
> cogit Jump: convertToIntAndReturn.
>
> jumpIsWords jmpTarget:
> (cogit CmpR: Arg1Reg R: nSlotsOrBytesReg).
> jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
> cogit AddCq: objectMemory baseHeaderSize >> (objectMemory
> shiftForWord - 1) R: Arg1Reg.
> cogit MoveX32r: Arg1Reg R: ReceiverResultReg R: TempReg.
> cogit MoveR: TempReg R: ReceiverResultReg.
> cogit Jump: convertToIntAndReturn.
>
> jumpHasFixedFields jmpTarget:
> (cogit AndCq: objectMemory classIndexMask R: TempReg).
> cogit MoveR: TempReg R: formatReg.
> cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
> jumpIsContext := cogit JumpZero: 0.
> self genGetClassObjectOfClassIndex: formatReg into: Extra0Reg
> scratchReg: TempReg.
> self genLoadSlot: InstanceSpecificationIndex sourceReg: Extra0Reg
> destReg: formatReg.
> self genConvertSmallIntegerToIntegerInReg: formatReg.
> cogit
> AndCq: objectMemory fixedFieldsOfClassFormatMask R:
> formatReg;
> SubR: formatReg R: nSlotsOrBytesReg;
> CmpR: Arg1Reg R: nSlotsOrBytesReg.
> jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
> "index is (formatReg (fixed fields) + Arg1Reg (0-rel index)) *
> wordSize + baseHeaderSize"
> cogit AddR: formatReg R: Arg1Reg.
> cogit AddCq: objectMemory baseHeaderSize >> objectMemory
> shiftForWord R: Arg1Reg.
> cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
> cogit genPrimReturn.
>
> + jumpIsLongs jmpTarget:
> + (cogit CmpR: Arg1Reg R: nSlotsOrBytesReg).
> + jumpLongsOutOfBounds := cogit JumpBelowOrEqual: 0.
> + cogit AddCq: objectMemory baseHeaderSize >> objectMemory
> shiftForWord R: Arg1Reg.
> + cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ClassReg.
> + cogit MoveR: ClassReg R: TempReg.
> + cogit LogicalShiftRightCq: self numSmallIntegerBits R: TempReg.
> "If in range this is now 0"
> + (cogit lastOpcode setsConditionCodesFor: JumpZero) ifFalse:
> + [cogit CmpCq: 0 R: ClassReg]. "N.B. FLAGS := ClassReg - 0"
> + jumpNotSmallInteger := cogit JumpNonZero: 0.
> + cogit MoveR: ClassReg R: ReceiverResultReg.
> + cogit Jump: convertToIntAndReturn.
> + jumpNotSmallInteger jmpTarget: cogit Label.
> + jumpFailAlloc := self genAlloc64BitIntegerValue: ClassReg into:
> SendNumArgsReg scratchReg: Extra0Reg scratchReg: TempReg.
> + cogit MoveR: SendNumArgsReg R: ReceiverResultReg.
> + cogit genPrimReturn.
> +
> jumpIsMethod jmpTarget: cogit Label.
> "Now check that the index is beyond the method's literals..."
> self getLiteralCountOf: ReceiverResultReg plusOne: true inBytes:
> true into: nSlotsOrBytesReg scratch: TempReg.
> cogit CmpR: Arg1Reg R: nSlotsOrBytesReg.
> cogit JumpBelow: methodInBounds.
>
> + jumpFailAlloc jmpTarget:
> + (jumpLongsOutOfBounds jmpTarget:
> + (jumpFixedFieldsOutOfBounds jmpTarget:
> - jumpFixedFieldsOutOfBounds jmpTarget:
> (jumpArrayOutOfBounds jmpTarget:
> (jumpBytesOutOfBounds jmpTarget:
> (jumpShortsOutOfBounds jmpTarget:
> (jumpWordsOutOfBounds jmpTarget:
> (jumpNotIndexable jmpTarget:
> (jumpIsContext jmpTarget:
> (jumpBadIndex jmpTarget:
> + (jumpImmediate jmpTarget: cogit Label)))))))))).
> - (jumpImmediate jmpTarget: cogit Label)))))))).
>
> ^0!
>
> Item was changed:
> SharedPool subclass: #CogRTLOpcodes
> instanceVariableNames: ''
> + classVariableNames: 'AddCqR AddCwR AddRR AddRdRd AddRsRs AddcCqR
> AddcRR AlignmentNops AndCqR AndCqRR AndCwR AndRR ArithmeticShiftRightCqR
> ArithmeticShiftRightRR Call CallFull CallR 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 LogicalShiftLeftRR
> LogicalShiftRightCqR LogicalShiftRightRR MoveA32R MoveAbR MoveAwR MoveC32R
> MoveCqR MoveCwR MoveM16rR MoveM32rR MoveM32rRs MoveM64rRd MoveM8rR MoveMbrR
> MoveMs8rR MoveM
> wrR 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 SubRdRd SubRsRs SubbCqR SubbRR TstCqR XorCqR XorCwR XorRR
> XorRdRd XorRsRs ZeroExtend16RR ZeroExtend32RR ZeroExtend8RR'
> - classVariableNames: 'AddCqR AddCwR AddRR AddRdRd AddRsRs AddcCqR
> AddcRR AlignmentNops AndCqR AndCqRR AndCwR AndRR ArithmeticShiftRightCqR
> ArithmeticShiftRightRR Call CallFull CallR 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 LoadEffectiveAddressXowrR LogicalShiftLeftCqR
> LogicalShiftLeftRR LogicalShiftRightCqR LogicalShiftRightRR MoveA32R
> MoveAbR MoveAwR MoveC32R MoveC64R MoveCqR MoveCwR MoveM16rR MoveM32rR
> MoveM32rRs MoveM64rR
> d MoveM8rR MoveMbrR MoveMs8rR MoveMwrR MoveRA32 MoveRAb MoveRAw MoveRM16r
> MoveRM32r MoveRM8r MoveRMbr MoveRMwr MoveRR MoveRRd MoveRX16rR MoveRX32rR
> MoveRXbrR MoveRXowr MoveRXwrR MoveRdM64r MoveRdR MoveRdRd MoveRsM32r
> MoveRsRs MoveX16rRR MoveX32rRR MoveXbrRR MoveXowrR 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 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') -----
> initialize
> "Abstract opcodes are a compound of a one word operation specifier
> and zero or more operand type specifiers.
> The assembler is in Cogit protocol abstract instructions and uses
> `at&t' syntax, assigning to the register on the
> right. e.g. MoveRR is the Move opcode with two register operand
> specifiers and defines a move register to
> register instruction from operand 0 to operand 1. The word and
> register size is assumed to be either 32-bits
> on a 32-bit architecture or 64-bits on a 64-bit architecture.
> The abstract machine is mostly a 2 address machine
> with the odd three address instruction added to better exploit
> RISCs.
> (self initialize)
> The operand specifiers are
> R - general purpose register
> Rs - single-precision floating-point register
> Rd - double-precision floating-point register
> Cq - a `quick' constant that can be encoded
> in the minimum space possible.
> Cw - a constant with word size where word is
> the default operand size for the Smalltalk VM, 32-bits
> for a 32-bit VM, 64-bits for a 64-bit
> VM. The generated constant must occupy the default number
> of bits. This allows e.g. a garbage
> collector to update the value without invalidating the code.
> C32 - a constant with 32 bit size. The generated
> constant must occupy 32 bits.
> C64 - a constant with 64 bit size. The generated
> constant must occupy 64 bits.
> Aw - memory word (32-bits for a 32-bit VM,
> 64-bits for a 64-bit VM) at an absolute address
> Ab - memory byte at an absolute address
> A32 - memory 32-bit halfword at an absolute address
> Mwr - memory word whose address is at a constant
> offset from an address in a register
> Mbr - memory byte whose address is at a
> constant offset from an address in a register (zero-extended on read)
> M16r - memory 16-bit halfword whose address is at a
> constant offset from an address in a register
> M32r - memory 32-bit halfword whose address is at a
> constant offset from an address in a register
> M64r - memory 64-bit doubleword whose address is at a
> constant offset from an address in a register
> Xbr - memory byte whose address is r * byte
> size away from an address in a register
> X16r - memory 16-bit halfword whose address is r * (2
> bytes size) away from an address in a register
> + X32r - memory 32-bit halfword whose address is r * (4
> bytes size) away from an address in a register (64-bit ISAs only)
> - X32r - memory 32-bit halfword whose address is r * (4
> bytes size) away from an address in a register
> Xwr - memory word whose address is r * word
> size away from an address in a register
> Xowr - memory word whose address is o + (r * word size)
> away from an address in a register (scaled indexed)
>
> An alternative would be to decouple opcodes from operands, e.g.
> Move := 1. Add := 2. Sub := 3...
> RegisterOperand := 1. ConstantQuickOperand := 2.
> ConstantWordOperand := 3...
> But not all combinations make sense and even fewer are used so we
> stick with the simple compound approach.
>
> The assumption is that comparison and arithmetic instructions set
> condition codes and that move instructions
> leave the condition codes unaffected. In particular
> LoadEffectiveAddressMwrR does not set condition codes
> although it can be used to do arithmetic. On processors such as
> MIPS this distinction is invalid; there are no
> + condition codes. So the backend is allowed to collapse operation,
> branch pairs to internal instruction definitions
> + (see senders and implementors of noteFollowingConditionalBranch:).
> - condition codes. So the backend is allowed to collapse operation,
> branch pairs to internal instruciton definitions
> - (see sender and implementors of noteFollowingConditionalBranch:).
>
> Not all of the definitions in opcodeDefinitions below are
> implemented. In particular we do not implement the
> XowrR scaled index addressing mode since it requires 4 operands.
>
> Not all instructions make sense on all architectures. MoveRRd and
> MoveRdR aqre meaningful only on 64-bit machines.
>
> Note that there are no generic division instructions defined, but
> a processor may define some.
>
> Branch/Call ranges. Jump[Cond] can be generated as short as
> possible. Call/Jump[Cond]Long must be generated
> in the same number of bytes irrespective of displacement since
> their targets may be updated, but they need only
> span 16Mb, the maximum size of the code zone. This allows e.g.
> ARM to use single-word call and jump instructions
> for most calls and jumps. CallFull/JumpFull must also be
> generated in the same number of bytes irrespective of
> displacement for the same reason, but they must be able to span
> the full (32-bit or 64-bit) address space because
> they are used to call code in the C runtime, which may be distant
> from the code zone. CallFull/JumpFull are allowed
> to use the cResultRegister as a scratch if required (e.g. on x64
> where there is no direct 64-bit call or jump).
>
> Byte reads. If the concrete compiler class answers true to
> byteReadsZeroExtend then byte reads must zero-extend
> the byte read into the destination register. If not, the other
> bits of the register should be left undisturbed and the
> Cogit will add an instruction to zero the register as required.
> Under no circumstances should byte reads sign-extend.
>
> 16-bit (and on 64-bits, 32-bit) reads. These /are/ expected to
> always zero-extend."
>
> | opcodeNames refs |
> opcodeNames := #("Noops & Pseudo Ops"
> Label
> Literal "a
> word-sized literal"
> AlignmentNops
> Fill32
> "output four byte's worth of bytes with operand 0"
> Nop
>
> "Control"
> Call
> "call within the code zone"
> CallFull
> "call anywhere within the full address space"
> CallR
> RetN
> JumpR
> "Not a regular jump, i.e. not pc dependent."
> Stop
> "Halt the processor"
>
> "N.B. Jumps are
> contiguous. Long and Full jumps are contiguous within them. See FirstJump
> et al below"
> JumpFull
> "Jump anywhere within the address space"
> JumpLong
> "Jump anywhere within the 16mb code zone."
> JumpLongZero
> "a.k.a. JumpLongEqual"
> JumpLongNonZero
> "a.k.a. JumpLongNotEqual"
> Jump
> "short jumps; can be encoded in as few bytes as possible; will not be
> disturbed by GC or relocation."
> JumpZero
> "a.k.a. JumpEqual"
> JumpNonZero
> "a.k.a. JumpNotEqual"
> JumpNegative
> JumpNonNegative
> JumpOverflow
> JumpNoOverflow
> JumpCarry
> JumpNoCarry
> JumpLess
> "signed"
> JumpGreaterOrEqual
> JumpGreater
> JumpLessOrEqual
> JumpBelow
> "unsigned"
> JumpAboveOrEqual
> JumpAbove
> JumpBelowOrEqual
>
> JumpFPEqual
> JumpFPNotEqual
> JumpFPLess
> JumpFPLessOrEqual
> JumpFPGreater
> JumpFPGreaterOrEqual
> JumpFPOrdered
> JumpFPUnordered
>
> "Data Movement;
> destination is always last operand"
> MoveRR
> MoveAwR MoveA32R
> MoveRAw MoveRA32
> MoveAbR
> MoveRAb
> + MoveMwrR MoveRMwr
> MoveXwrRR MoveRXwrR "MoveXowrR MoveRXowr""Unused"
> - MoveMwrR MoveRMwr
> MoveXwrRR MoveRXwrR MoveXowrR MoveRXowr
> MoveM8rR MoveMs8rR MoveRM8r
> MoveM16rR MoveRM16r
> MoveX16rRR MoveRX16rR
> MoveM32rR MoveRM32r
> MoveX32rRR MoveRX32rR
> MoveMbrR MoveRMbr
> MoveXbrRR MoveRXbrR
> + MoveCqR MoveCwR MoveC32R
> "MoveC64R""Not used"
> - MoveCqR MoveCwR MoveC32R
> MoveC64R
> MoveRRd MoveRdR MoveRdRd
> MoveM64rRd MoveRdM64r
> MoveRsRs MoveM32rRs
> MoveRsM32r
> PopR PushR PushCq PushCw
> PrefetchAw
>
> "Arithmetic; destination
> is always last operand except Cmp; CmpXR is SubRX with no update of result"
> + LoadEffectiveAddressMwrR
> "LoadEffectiveAddressXowrR" "Variants of add/multiply"
> - LoadEffectiveAddressMwrR
> LoadEffectiveAddressXowrR "Variants of add/multiply"
> NegateR "2's complement
> negation"
> NotR
> ArithmeticShiftRightCqR
> ArithmeticShiftRightRR
> LogicalShiftRightCqR
> LogicalShiftRightRR
> LogicalShiftLeftCqR
> LogicalShiftLeftRR
> RotateLeftCqR
> RotateRightCqR
>
> CmpRR AddRR SubRR AndRR
> OrRR XorRR
> CmpCqR AddCqR SubCqR
> AndCqR OrCqR TstCqR XorCqR
> CmpCwR CmpC32R AddCwR
> SubCwR AndCwR OrCwR XorCwR
> AddcRR AddcCqR SubbRR
> SubbCqR
>
> AndCqRR "Three address ops
> for RISCs; feel free to add and extend"
>
> CmpRdRd AddRdRd SubRdRd
> MulRdRd DivRdRd SqrtRd XorRdRd
> CmpRsRs AddRsRs SubRsRs
> MulRsRs DivRsRs SqrtRs XorRsRs
>
> "Conversion"
> ConvertRRd ConvertRdR
> ConvertRsRd ConvertRdRs
> ConvertRsR ConvertRRs
>
> SignExtend8RR
> SignExtend16RR SignExtend32RR
> ZeroExtend8RR
> ZeroExtend16RR ZeroExtend32RR
>
> LastRTLCode).
>
> "Magic auto declaration. Add to the classPool any new variables
> and nuke any obsolete ones, and assign values"
> "Find the variables directly referenced by this method"
> refs := (thisContext method literals select: [:l| l
> isVariableBinding and: [classPool includesKey: l key]]) collect:
> [:ea| ea key].
> "Move to Undeclared any opcodes in classPool not in opcodes or
> this method."
> (classPool keys reject: [:k| (opcodeNames includes: k) or: [refs
> includes: k]]) do:
> [:k|
> Undeclared declare: k from: classPool].
> "Declare as class variables and number elements of opcodeArray
> above"
> opcodeNames withIndexDo:
> [:classVarName :value|
> self classPool
> declare: classVarName from: Undeclared;
> at: classVarName put: value].
>
> "For CogAbstractInstruction>>isJump etc..."
> FirstJump := JumpFull.
> LastJump := JumpFPUnordered.
> FirstShortJump := Jump.
>
> "And now initialize the backends; they add their own opcodes and
> hence these must be reinitialized."
> (Smalltalk classNamed: #CogAbstractInstruction) ifNotNil:
> [:cogAbstractInstruction| cogAbstractInstruction
> allSubclasses do: [:sc| sc initialize]]!
>
> Item was changed:
> ----- Method: CogX64Compiler>>setsConditionCodesFor: (in category
> 'testing') -----
> setsConditionCodesFor: aConditionalJumpOpcode
> <inline: false> "to save Slang from having to be a real compiler
> (it can't inline switches that return)"
> "Answer if the receiver's opcode sets the condition codes
> correctly for the given conditional jump opcode."
> ^opcode caseOf:
> { [ArithmeticShiftRightCqR] -> [self
> shiftSetsConditionCodesFor: aConditionalJumpOpcode].
> [ArithmeticShiftRightRR] -> [self
> shiftSetsConditionCodesFor: aConditionalJumpOpcode].
> [LogicalShiftLeftCqR] -> [self
> shiftSetsConditionCodesFor: aConditionalJumpOpcode].
> [LogicalShiftLeftRR] -> [self
> shiftSetsConditionCodesFor: aConditionalJumpOpcode].
> + [LogicalShiftRightCqR] -> [self
> shiftSetsConditionCodesFor: aConditionalJumpOpcode].
> [XorRR] ->
> [true]
> }
> otherwise: [self halt: 'unhandled opcode in
> setsConditionCodesFor:'. false]!
>
> Item was added:
> + ----- Method: CurrentImageCoInterpreterFacade>>sixtyFourBitIndexableFormat
> (in category 'accessing') -----
> + sixtyFourBitIndexableFormat
> + ^objectMemory sixtyFourBitIndexableFormat!
>
>
--
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20171220/4c01d8f8/attachment-0001.html>
More information about the Vm-dev
mailing list