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