Lars Wassermann uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-lw.191.mcz
==================== Summary ====================
Name: VMMaker.oscog-lw.191 Author: lw Time: 31 July 2012, 3:46:30.782 pm UUID: 646aea3c-a1b4-ab40-a9e6-46861b3c0aa2 Ancestors: VMMaker.oscog-eem.190
- added the shift opcodes
- added AddCqR and SubCqR, which test for negative immediates, which allows the compiler to exchange Add r0, r0, #-2 to Sub r0, r0, #2 and thus saves 4 instructions, 16 byte
- changed all the remaining AbstractInstructionTests test cases to allow multiple single stepping
- added NegateR test as another place of documentation for the NegateR opcode (twos complement, not ones)
- extracted the offset computation which is the same in all the different concretizeConditionalJump methods. Unfortunately, the computation includes a constant, which might get the address to overflow. In the image, this would result in a large integer, while in C, this would result in a negative number. Therefore, the methods signature is weird (CogAbstractInstruction>>computeJumpTargetOffsetPlus:).
=============== Diff against VMMaker.oscog-eem.190 ===============
Item was changed: ----- Method: AbstractInstructionTests>>runAddCwR: (in category 'running') ----- runAddCwR: assertPrintBar "self defaultTester runAddCwR: false" | memory | + memory := ByteArray new: self concreteCompilerClass new machineCodeBytes. - memory := ByteArray new: 16. self concreteCompilerClass dataRegistersWithAccessorsDo: [:reg :rgetter :rsetter| self pairs: (-2 to: 2) do: [:a :b| | inst len bogus | inst := self gen: AddCwR operand: a operand: reg. len := inst concretizeAt: 0. memory replaceFrom: 1 to: len with: inst machineCode object startingAt: 1. self processor reset; + perform: rsetter with: b signedIntToLong. + [[processor pc < len] whileTrue: + [self processor singleStepIn: memory]] + on: Error + do: [:ex| ]. - perform: rsetter with: b signedIntToLong; - singleStepIn: memory. "self processor printRegistersOn: Transcript. Transcript show: (self processor disassembleInstructionAt: 0 In: memory); cr" assertPrintBar ifTrue: [self assert: processor pc = inst machineCodeSize. self assertCheckLongArithOpCodeSize: inst machineCodeSize] ifFalse: [bogus := processor pc ~= inst machineCodeSize]. self concreteCompilerClass dataRegistersWithAccessorsDo: [:ireg :getter :setter| | expected | expected := getter == rgetter ifTrue: [a + b] ifFalse: [0]. assertPrintBar ifTrue: [self assert: (self processor perform: getter) signedIntFromLong = expected] ifFalse: [(self processor perform: getter) signedIntFromLong ~= expected ifTrue: [bogus := true]]]. assertPrintBar ifFalse: [Transcript nextPutAll: rgetter; nextPut: $(; print: b; nextPutAll: ') + '; print: a; nextPutAll: ' = '; print: (self processor perform: rgetter) signedIntFromLong; cr; flush. bogus ifTrue: [self processor printRegistersOn: Transcript. Transcript show: (self processor disassembleInstructionAt: 0 In: memory); cr]]]]!
Item was changed: ----- Method: AbstractInstructionTests>>runAddRR: (in category 'running') ----- runAddRR: assertPrintBar "self defaultTester runAddRR: false" "self defaultTester runAddRR: true" | memory | memory := ByteArray new: 16. self concreteCompilerClass dataRegistersWithAccessorsDo: [:sreg :srgetter :srsetter| self concreteCompilerClass dataRegistersWithAccessorsDo: [:dreg :drgetter :drsetter| | inst len | inst := self gen: AddRR operand: sreg operand: dreg. len := inst concretizeAt: 0. memory replaceFrom: 1 to: len with: inst machineCode object startingAt: 1. self pairs: (-2 to: 2) do: [:a :b| | bogus | self processor reset; perform: srsetter with: a signedIntToLong; + perform: drsetter with: b signedIntToLong. + [[processor pc < len] whileTrue: + [self processor singleStepIn: memory]] + on: Error + do: [:ex| ]. - perform: drsetter with: b signedIntToLong; - singleStepIn: memory. "self processor printRegistersOn: Transcript. Transcript show: (self processor disassembleInstructionAt: 0 In: memory); cr" assertPrintBar ifTrue: [self assert: processor pc = inst machineCodeSize] ifFalse: [bogus := processor pc ~= inst machineCodeSize]. self concreteCompilerClass dataRegistersWithAccessorsDo: [:ireg :getter :setter| | expected | expected := getter == drgetter ifTrue: [srgetter == drgetter ifTrue: [b + b] ifFalse: [a + b]] ifFalse: [getter = srgetter ifTrue: [a] ifFalse: [0]]. assertPrintBar ifTrue: [self assert: (self processor perform: getter) signedIntFromLong = expected] ifFalse: [(self processor perform: getter) signedIntFromLong ~= expected ifTrue: [bogus := true]]]. assertPrintBar ifFalse: [Transcript nextPutAll: drgetter; nextPut: $(; print: b; nextPutAll: ') + '; nextPutAll: srgetter; nextPut: $(; print: a; nextPutAll: ') = '; print: (self processor perform: drgetter) signedIntFromLong; cr; flush. bogus ifTrue: [self processor printRegistersOn: Transcript. Transcript show: (self processor disassembleInstructionAt: 0 In: memory); cr]]]]]!
Item was changed: ----- Method: AbstractInstructionTests>>runSubCqR: (in category 'running') ----- runSubCqR: assertPrintBar "self defaultTester runSubCqR: false" | memory | memory := ByteArray new: 16. self concreteCompilerClass dataRegistersWithAccessorsDo: [:reg :rgetter :rsetter| self pairs: (-2 to: 2) do: [:a :b| | inst len bogus | inst := self gen: SubCqR operand: a operand: reg. len := inst concretizeAt: 0. memory replaceFrom: 1 to: len with: inst machineCode object startingAt: 1. self processor reset; + perform: rsetter with: b signedIntToLong. + [[processor pc < len] whileTrue: + [self processor singleStepIn: memory]] + on: Error + do: [:ex| ]. - perform: rsetter with: b signedIntToLong; - singleStepIn: memory. "self processor printRegistersOn: Transcript. Transcript show: (self processor disassembleInstructionAt: 0 In: memory); cr" assertPrintBar ifTrue: [self assert: processor pc = inst machineCodeSize. self assertCheckQuickArithOpCodeSize: inst machineCodeSize] ifFalse: [bogus := processor pc ~= inst machineCodeSize]. self concreteCompilerClass dataRegistersWithAccessorsDo: [:ireg :getter :setter| | expected | expected := getter == rgetter ifTrue: [b - a] ifFalse: [0]. assertPrintBar ifTrue: [self assert: (self processor perform: getter) signedIntFromLong = expected] ifFalse: [(self processor perform: getter) signedIntFromLong ~= expected ifTrue: [bogus := true]]]. assertPrintBar ifFalse: [Transcript nextPutAll: rgetter; nextPut: $(; print: b; nextPutAll: ') - '; print: a; nextPutAll: ' = '; print: (self processor perform: rgetter) signedIntFromLong; cr; flush. bogus ifTrue: [self processor printRegistersOn: Transcript. Transcript show: (self processor disassembleInstructionAt: 0 In: memory); cr]]]]!
Item was changed: ----- Method: AbstractInstructionTests>>runSubCwR: (in category 'running') ----- runSubCwR: assertPrintBar "self defaultTester runSubCwR: false" | memory | + memory := ByteArray new: self concreteCompilerClass new machineCodeBytes. - memory := ByteArray new: 16. self concreteCompilerClass dataRegistersWithAccessorsDo: [:reg :rgetter :rsetter| self pairs: (-2 to: 2) do: [:a :b| | inst len bogus | inst := self gen: SubCwR operand: a operand: reg. len := inst concretizeAt: 0. memory replaceFrom: 1 to: len with: inst machineCode object startingAt: 1. self processor reset; + perform: rsetter with: b signedIntToLong. + [[processor pc < len] whileTrue: + [self processor singleStepIn: memory]] + on: Error + do: [:ex| ]. - perform: rsetter with: b signedIntToLong; - singleStepIn: memory. "self processor printRegistersOn: Transcript. Transcript show: (self processor disassembleInstructionAt: 0 In: memory); cr" assertPrintBar ifTrue: [self assert: processor pc = inst machineCodeSize. self assertCheckLongArithOpCodeSize: inst machineCodeSize] ifFalse: [bogus := processor pc ~= inst machineCodeSize]. self concreteCompilerClass dataRegistersWithAccessorsDo: [:ireg :getter :setter| | expected | expected := getter == rgetter ifTrue: [b - a] ifFalse: [0]. assertPrintBar ifTrue: [self assert: (self processor perform: getter) signedIntFromLong = expected] ifFalse: [(self processor perform: getter) signedIntFromLong ~= expected ifTrue: [bogus := true]]]. assertPrintBar ifFalse: [Transcript nextPutAll: rgetter; nextPut: $(; print: b; nextPutAll: ') - '; print: a; nextPutAll: ' = '; print: (self processor perform: rgetter) signedIntFromLong; cr; flush. bogus ifTrue: [self processor printRegistersOn: Transcript. Transcript show: (self processor disassembleInstructionAt: 0 In: memory); cr]]]]!
Item was changed: ----- Method: AbstractInstructionTests>>runSubRR: (in category 'running') ----- runSubRR: assertPrintBar "self defaultTester runSubRR: false" | memory | + memory := ByteArray new: self concreteCompilerClass new machineCodeBytes. - memory := ByteArray new: 16. self concreteCompilerClass dataRegistersWithAccessorsDo: [:sreg :srgetter :srsetter| self concreteCompilerClass dataRegistersWithAccessorsDo: [:dreg :drgetter :drsetter| | inst len | inst := self gen: SubRR operand: sreg operand: dreg. len := inst concretizeAt: 0. memory replaceFrom: 1 to: len with: inst machineCode object startingAt: 1. self pairs: (-2 to: 2) do: [:a :b| | bogus | self processor reset; perform: srsetter with: a signedIntToLong; + perform: drsetter with: b signedIntToLong. + [[processor pc < len] whileTrue: + [self processor singleStepIn: memory]] + on: Error + do: [:ex| ]. - perform: drsetter with: b signedIntToLong; - singleStepIn: memory. "self processor printRegistersOn: Transcript. Transcript show: (self processor disassembleInstructionAt: 0 In: memory); cr" assertPrintBar ifTrue: [self assert: processor pc = inst machineCodeSize] ifFalse: [bogus := processor pc ~= inst machineCodeSize]. self concreteCompilerClass dataRegistersWithAccessorsDo: [:ireg :getter :setter| | expected | expected := drgetter == srgetter ifTrue: [0] ifFalse: [getter == drgetter ifTrue: [b - a] ifFalse: [getter = srgetter ifTrue: [a] ifFalse: [0]]]. assertPrintBar ifTrue: [self assert: (self processor perform: getter) signedIntFromLong = expected] ifFalse: [(self processor perform: getter) signedIntFromLong ~= expected ifTrue: [bogus := true]]]. assertPrintBar ifFalse: [Transcript nextPutAll: drgetter; nextPut: $(; print: b; nextPutAll: ') - '; nextPutAll: srgetter; nextPut: $(; print: a; nextPutAll: ') = '; print: (self processor perform: drgetter) signedIntFromLong; cr; flush. bogus ifTrue: [self processor printRegistersOn: Transcript. Transcript show: (self processor disassembleInstructionAt: 0 In: memory); cr]]]]]!
Item was added: + ----- Method: AbstractInstructionTests>>testNegateR (in category 'running') ----- + testNegateR + "self defaultTester testNegateR" + | memory | + memory := ByteArray new: self concreteCompilerClass new machineCodeBytes. + self concreteCompilerClass dataRegistersWithAccessorsDo: + [:reg :rgetter :rsetter| + -2 to: 2 do: + [:a| | inst len | + inst := self gen: NegateR operand: reg. + len := inst concretizeAt: 0. + memory replaceFrom: 1 to: len with: inst machineCode object startingAt: 1. + self processor + reset; + perform: rsetter with: a signedIntToLong. + [[processor pc < len] whileTrue: + [self processor singleStepIn: memory]] + on: Error + do: [:ex| ]. + "self processor printRegistersOn: Transcript. + Transcript show: (self processor disassembleInstructionAt: 0 In: memory); cr" + self assert: processor pc = inst machineCodeSize. + self concreteCompilerClass dataRegistersWithAccessorsDo: + [:ireg :getter :setter| | expected | + expected := getter == rgetter ifTrue: [ a negated ] ifFalse: [0]. + self assert: (self processor perform: getter) signedIntFromLong = expected]]]!
Item was added: + ----- Method: CogARMCompiler>>callsAreRelative (in category 'testing') ----- + callsAreRelative + ^true!
Item was added: + ----- Method: CogARMCompiler>>canDivQuoRem (in category 'testing') ----- + canDivQuoRem + ^false!
Item was added: + ----- Method: CogARMCompiler>>canMulRR (in category 'testing') ----- + canMulRR + ^true!
Item was added: + ----- Method: CogARMCompiler>>concretizeAddCqR (in category 'generate machine code - concretize') ----- + concretizeAddCqR + "Will get inlined into concretizeAt: switch." + "Try whether the quick constant is a small negative number. If it is, optimize." + <inline: true> + ^self rotateable8bitImmediate: (operands at: 0) + ifTrue: [ :rot :immediate | | reg | + reg := self concreteRegister: (operands at: 1). + self machineCodeAt: 0 put: ((self t: 1 o: 4 s: 1) bitOr: reg << 16). + machineCode at: 0 put: immediate. + machineCode at: 1 put: (reg << 4 bitOr: rot). + ^machineCodeSize := 4] + ifFalse: [ + self rotateable8bitImmediate: (operands at: 0) negated + ifTrue: [ :r :i | + opcode := SubCqR. + operands at: 0 put: (operands at: 0) negated. + self concretizeDataOperationCqR: 2] + ifFalse: [self concretizeDataOperationCwR: 4]]!
Item was added: + ----- Method: CogARMCompiler>>concretizeArithmeticShiftRightCqR (in category 'generate machine code - concretize') ----- + concretizeArithmeticShiftRightCqR + "Will get inlined into concretizeAt: switch." + <inline: true> + | distance reg | + distance := (operands at: 0) min: 31. + reg := self concreteRegister: (operands at: 1). + "cond 000 1101 0 0000 dest dist -100 srcR" + self machineCodeAt: 0 put: ((self t: 0 o: 16rD s: 0 rn: 0 rd: reg) + bitOr: (distance << 7 bitOr: (64 bitOr: reg))). + ^machineCodeSize := 4!
Item was added: + ----- Method: CogARMCompiler>>concretizeArithmeticShiftRightRR (in category 'generate machine code - concretize') ----- + concretizeArithmeticShiftRightRR + "Will get inlined into concretizeAt: switch." + <inline: true> + | destReg distReg | + distReg := self concreteRegister: (operands at: 0). + destReg := self concreteRegister: (operands at: 1). + "cond 000 1101 0 0000 dest dist 0101 srcR" + self machineCodeAt: 0 put: ((self t: 0 o: 16rD s: 0 rn: 0 rd: destReg) + bitOr: (distReg << 8 bitOr: (80 bitOr: destReg))). + ^machineCodeSize := 4!
Item was changed: ----- Method: CogARMCompiler>>concretizeConditionalJump: (in category 'generate machine code - concretize') ----- concretizeConditionalJump: conditionCode "Will get inlined into concretizeAt: switch." "Sizing/generating jumps. Jump targets can be to absolute addresses or other abstract instructions. Generating initial trampolines instructions may have no maxSize and be to absolute addresses. Otherwise instructions must have a machineCodeSize which must be kept to." <inline: true> + | offset | + offset := self computeJumpTargetOffsetPlus: 8. - | jumpTarget offset | - "TODO extract method: jumpTarget calculator together with CogIA32Compiler" - <var: #jumpTarget type: #'AbstractInstruction *'> - jumpTarget := cogit cCoerceSimple: (operands at: 0) to: #'AbstractInstruction *'. - cogit assertSaneJumpTarget: jumpTarget. - (self isAnInstruction: jumpTarget) ifTrue: - [jumpTarget := cogit cCoerceSimple: jumpTarget address to: #'AbstractInstruction *']. - self assert: jumpTarget ~= 0. - offset := jumpTarget signedIntFromLong - (address + 8) signedIntFromLong. (self isQuick: offset) ifTrue: [ self machineCodeAt: 0 put: (self t: 5 o: 8) + (offset >> 2 bitAnd: 16r00FFFFFF). "BL offset" ^machineCodeSize := 4] ifFalse: [ + self concretizeConditionalJumpLong: conditionCode]! - self halt]!
Item was added: + ----- Method: CogARMCompiler>>concretizeConditionalJumpLong: (in category 'generate machine code - concretize') ----- + concretizeConditionalJumpLong: conditionCode + "Will get inlined into concretizeAt: switch." + "Sizing/generating jumps. + Jump targets can be to absolute addresses or other abstract instructions. + Generating initial trampolines instructions may have no maxSize and be to absolute addresses. + Otherwise instructions must have a machineCodeSize which must be kept to." + <inline: true> + | offset | + offset := self computeJumpTargetOffsetPlus: 24 "16+8". + !
Item was changed: ----- Method: CogARMCompiler>>concretizeDataOperationRR: (in category 'generate machine code - concretize') ----- concretizeDataOperationRR: opcode "Will get inlined into concretizeAt: switch." "Load the word into the RISCTempReg, then cmp R, RISCTempReg" <inline: true> | destReg srcReg | srcReg := self concreteRegister: (operands at: 0). destReg := (self concreteRegister: (operands at: 1)). self machineCodeAt: 0 + put: ((self t: 0 o: opcode s: 1 rn: destReg rd: destReg) bitOr: srcReg). - put: ((self t: 0 o: opcode s: 1 rn: srcReg rd: destReg) bitOr: destReg). ^machineCodeSize := 4.!
Item was added: + ----- Method: CogARMCompiler>>concretizeLogicalShiftLeftCqR (in category 'generate machine code - concretize') ----- + concretizeLogicalShiftLeftCqR + "Will get inlined into concretizeAt: switch." + <inline: true> + | distance reg | + distance := (operands at: 0) min: 31. + reg := self concreteRegister: (operands at: 1). + "cond 000 1101 0 0000 dest dista 000 srcR" + self machineCodeAt: 0 put: ((self t: 0 o: 16rD s: 0 rn: 0 rd: reg) + bitOr: (distance << 7 bitOr: reg)). + ^machineCodeSize := 4!
Item was added: + ----- Method: CogARMCompiler>>concretizeLogicalShiftLeftRR (in category 'generate machine code - concretize') ----- + concretizeLogicalShiftLeftRR + "Will get inlined into concretizeAt: switch." + <inline: true> + | destReg distReg | + distReg := self concreteRegister: (operands at: 0). + destReg := self concreteRegister: (operands at: 1). + "cond 000 1101 0 0000 dest dist 0001 srcR" + self machineCodeAt: 0 put: ((self t: 0 o: 16rD s: 0 rn: 0 rd: destReg) + bitOr: (distReg << 8 bitOr: (16 bitOr: destReg))). + ^machineCodeSize := 4!
Item was added: + ----- Method: CogARMCompiler>>concretizeLogicalShiftRightCqR (in category 'generate machine code - concretize') ----- + concretizeLogicalShiftRightCqR + "Will get inlined into concretizeAt: switch." + <inline: true> + | distance reg | + distance := (operands at: 0) min: 31. + reg := self concreteRegister: (operands at: 1). + "cond 000 1101 0 0000 dest dist -010 srcR" + self machineCodeAt: 0 put: ((self t: 0 o: 16rD s: 0 rn: 0 rd: reg) + bitOr: (distance << 7 bitOr: (32 bitOr: reg))). + ^machineCodeSize := 4!
Item was added: + ----- Method: CogARMCompiler>>concretizeLogicalShiftRightRR (in category 'generate machine code - concretize') ----- + concretizeLogicalShiftRightRR + "Will get inlined into concretizeAt: switch." + <inline: true> + | destReg distReg | + distReg := self concreteRegister: (operands at: 0). + destReg := self concreteRegister: (operands at: 1). + "cond 000 1101 0 0000 dest dist 0011 srcR" + self machineCodeAt: 0 put: ((self t: 0 o: 16rD s: 0 rn: 0 rd: destReg) + bitOr: (distReg << 8 bitOr: (48 bitOr: destReg))). + ^machineCodeSize := 4!
Item was changed: ----- Method: CogARMCompiler>>concretizeNegateR (in category 'generate machine code - concretize') ----- concretizeNegateR "Will get inlined into concretizeAt: switch." - "All other data operations write back their results. The write back register should be zero for CMP." <inline: true> | reg | reg := self concreteRegister: (operands at: 0). + "rsb r0, r0, #0" + self machineCodeAt: 0 put: (self t: 1 o: 3 s: 0 rn: reg rd: reg). - self machineCodeAt: 0 put: ((self t: 0 o: 16rF s: 0 rn: 0 rd: reg) bitOr: reg). ^machineCodeSize := 4!
Item was added: + ----- Method: CogARMCompiler>>concretizeNop (in category 'generate machine code - concretize') ----- + concretizeNop + "Will get inlined into concretizeAt: switch." + <inline: true> + self machineCodeAt: 0 put: 16rE1A01001. + ^machineCodeSize := 4 + !
Item was added: + ----- Method: CogARMCompiler>>concretizeSubCqR (in category 'generate machine code - concretize') ----- + concretizeSubCqR + "Will get inlined into concretizeAt: switch." + "Try whether the quick constant is a small negative number. If it is, optimize." + <inline: true> + ^self rotateable8bitImmediate: (operands at: 0) + ifTrue: [ :rot :immediate | | reg | + reg := self concreteRegister: (operands at: 1). + self machineCodeAt: 0 put: ((self t: 1 o: 2 s: 1) bitOr: reg << 16). + machineCode at: 0 put: immediate. + machineCode at: 1 put: (reg << 4 bitOr: rot). + ^machineCodeSize := 4] + ifFalse: [ + self rotateable8bitImmediate: (operands at: 0) negated + ifTrue: [ :r :i | + opcode := AddCqR. + operands at: 0 put: (operands at: 0) negated. + self concretizeDataOperationCqR: 4] + ifFalse: [self concretizeDataOperationCwR: 2]]!
Item was changed: ----- Method: CogARMCompiler>>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: { "Noops & Pseudo Ops" [Label] -> [^self concretizeLabel]. [AlignmentNops] -> [^self concretizeAlignmentNops]. [Fill16] -> [^self concretizeFill16]. [Fill32] -> [^self concretizeFill32]. [FillFromWord] -> [^self concretizeFillFromWord]. [Nop] -> [^self concretizeNop]. "Specific Control/Data Movement" "[LDM] -> [^self concretizeLDM]. [STM] -> [^self concretizeSTM]." "Control" [Call] -> [^self concretizeCall]. [JumpR] -> [^self concretizeJumpR]. + [JumpLong] -> [^self concretizeConditionalJumpLong: AL]. + [JumpLongZero] -> [^self concretizeConditionalJumpLong: EQ]. + [JumpLongNonZero] -> [^self concretizeConditionalJumpLong: NE]. - [JumpLong] -> [^self concretizeJumpLong]. - "[JumpLongZero] -> [^self concretizeConditionalJumpLong: EQ]. - [JumpLongNonZero] -> [^self concretizeConditionalJumpLong: NE]." [Jump] -> [^self concretizeConditionalJump: AL]. [JumpZero] -> [^self concretizeConditionalJump: EQ]. [JumpNonZero] -> [^self concretizeConditionalJump: NE]. [JumpNegative] -> [^self concretizeConditionalJump: MI]. [JumpNonNegative] -> [^self concretizeConditionalJump: PL]. [JumpOverflow] -> [^self concretizeConditionalJump: VS]. [JumpNoOverflow] -> [^self concretizeConditionalJump: VC]. [JumpCarry] -> [^self concretizeConditionalJump: CS]. [JumpNoCarry] -> [^self concretizeConditionalJump: CC]. [JumpLess] -> [^self concretizeConditionalJump: LT]. [JumpGreaterOrEqual] -> [^self concretizeConditionalJump: GE]. [JumpGreater] -> [^self concretizeConditionalJump: GT]. [JumpLessOrEqual] -> [^self concretizeConditionalJump: LE]. [JumpBelow] -> [^self concretizeConditionalJump: CS]. "according to http://courses.engr.illinois.edu/ece390/books/labmanual/assembly.html" [JumpAboveOrEqual] -> [^self concretizeConditionalJump: CC]. " --""-- " [JumpAbove] -> [^self concretizeConditionalJump: HI]. [JumpBelowOrEqual] -> [^self concretizeConditionalJump: LS]. [JumpFPEqual] -> [^self concretizeFPConditionalJump: EQ]. [JumpFPNotEqual] -> [^self concretizeFPConditionalJump: NE]. "[JumpFPLess] -> [^self concretizeFPConditionalJump: LT]. [JumpFPGreaterOrEqual] -> [^self concretizeFPConditionalJump: GE]. [JumpFPGreater] -> [^self concretizeFPConditionalJump: GT]. [JumpFPLessOrEqual] -> [^self concretizeFPConditionalJump: LE]. [JumpFPOrdered] -> [^self concretizeFPConditionalJump: VC]. [JumpFPUnordered] -> [^self concretizeFPConditionalJump: VS]." [RetN] -> [^self concretizeRetN]. "Arithmetic" + [AddCqR] -> [^self concretizeAddCqR]. - [AddCqR] -> [^self concretizeDataOperationCqR: 4]. [AddCwR] -> [^self concretizeDataOperationCwR: 4]. [AddRR] -> [^self concretizeDataOperationRR: 4]. "[AddRdRd] -> [^self concretizeSEE2OpRdRd: 16r58]." [AndCqR] -> [^self concretizeDataOperationCqR: 0]. [AndCwR] -> [^self concretizeDataOperationCwR: 0]. [AndRR] -> [^self concretizeDataOperationRR: 0]. [CmpCqR] -> [^self concretizeCmpCqR]. [CmpCwR] -> [^self concretizeCmpCwR]. [CmpRR] -> [^self concretizeCmpRR]. [CmpRdRd] -> [^self concretizeCmpRdRd]. "[DivRdRd] -> [^self concretizeSEE2OpRdRd: 16r5E]. [MulRdRd] -> [^self concretizeSEE2OpRdRd: 16r59]." [OrCqR] -> [^self concretizeDataOperationCqR: 16rC]. [OrCwR] -> [^self concretizeDataOperationCwR: 16rC]. [OrRR] -> [^self concretizeDataOperationRR: 16rC]. + [SubCqR] -> [^self concretizeSubCqR]. - [SubCqR] -> [^self concretizeDataOperationCqR: 2]. [SubCwR] -> [^self concretizeDataOperationCwR: 2]. [SubRR] -> [^self concretizeDataOperationRR: 2]. "[SubRdRd] -> [^self concretizeSEE2OpRdRd: 16r5C]." [SqrtRd] -> [^self concretizeSqrtRd]. [XorCqR] -> [^self concretizeDataOperationCqR: 1]. [XorCwR] -> [^self concretizeDataOperationCwR: 1]. [XorRR] -> [^self concretizeDataOperationRR: 1]. [NegateR] -> [^self concretizeNegateR]. [LoadEffectiveAddressMwrR] -> [^self concretizeLoadEffectiveAddressMwrR]. [ArithmeticShiftRightCqR] -> [^self concretizeArithmeticShiftRightCqR]. [LogicalShiftRightCqR] -> [^self concretizeLogicalShiftRightCqR]. [LogicalShiftLeftCqR] -> [^self concretizeLogicalShiftLeftCqR]. [ArithmeticShiftRightRR] -> [^self concretizeArithmeticShiftRightRR]. [LogicalShiftLeftRR] -> [^self concretizeLogicalShiftLeftRR]. + [LogicalShiftRightRR] -> [^self concretizeLogicalShiftRightRR]. "Data Movement" [MoveCqR] -> [^self concretizeMoveCqR]. [MoveCwR] -> [^self concretizeMoveCwR]. [MoveRR] -> [^self concretizeMoveRR]. [MoveAwR] -> [^self concretizeMoveAwR]. [MoveRAw] -> [^self concretizeMoveRAw]. [MoveMbrR] -> [^self concretizeMoveMbrR]. [MoveRMbr] -> [^self concretizeMoveRMbr]. [MoveM16rR] -> [^self concretizeMoveM16rR]. [MoveM64rRd] -> [^self concretizeMoveM64rRd]. [MoveMwrR] -> [^self concretizeMoveMwrR]. [MoveXbrRR] -> [^self concretizeMoveXbrRR]. [MoveXwrRR] -> [^self concretizeMoveXwrRR]. [MoveRXwrR] -> [^self concretizeMoveRXwrR]. [MoveRMwr] -> [^self concretizeMoveRMwr]. [MoveRdM64r] -> [^self concretizeMoveRdM64r]. [PopR] -> [^self concretizePopR]. [PushR] -> [^self concretizePushR]. [PushCw] -> [^self concretizePushCw]. [PrefetchAw] -> [^self concretizePrefetchAw]. "Conversion" + [ConvertRRd] -> [^self concretizeConvertRRd]. + "ARM specific opcodes" + [LDMFD] -> [^self concretizeLDMFD]. + [STMFD] -> [^self concretizeSTMFD] }! - [ConvertRRd] -> [^self concretizeConvertRRd] }!
Item was added: + ----- Method: CogARMCompiler>>genRestoreRegisters (in category 'abi') ----- + genRestoreRegisters + "Load the general purpose registers after the return of a trampoline call." + "Load r0-r6, all of which were saved. Don't load sb(r9), sl(r10), fp(r11), sp or lr" + cogit + gen: LDMFD operand: 16r7F!
Item was added: + ----- Method: CogARMCompiler>>hasDoublePrecisionFloatingPointSupport (in category 'testing') ----- + hasDoublePrecisionFloatingPointSupport + "might be true, but is for the forseeable future disabled" + ^false!
Item was added: + ----- Method: CogARMCompiler>>hasLinkRegister (in category 'testing') ----- + hasLinkRegister + ^true "lr"!
Item was added: + ----- Method: CogARMCompiler>>hasPCDependentInstruction (in category 'testing') ----- + hasPCDependentInstruction + "e.g. B, BL: Branch, Branch and Link" + ^true!
Item was added: + ----- Method: CogARMCompilerForTests class>>fp64RegistersWithAccessorsDo: (in category 'test support') ----- + fp64RegistersWithAccessorsDo: aBlock + "there are none, because we do not support VFP, yet"!
Item was added: + ----- Method: CogARMCompilerTests>>assertCheckLongArithOpCodeSize: (in category 'running') ----- + assertCheckLongArithOpCodeSize: bytes + self assert: bytes > 4!
Item was changed: ----- Method: CogARMCompilerTests>>assertCheckQuickArithOpCodeSize: (in category 'running') ----- assertCheckQuickArithOpCodeSize: bytes "The problem is that there are negative value, which are not quick encodable in ARM" + self assert: bytes <= 4! - self assert: bytes <= 20!
Item was added: + ----- Method: CogARMCompilerTests>>assertSaneJumpTarget: (in category 'cogit compiler compatibility') ----- + assertSaneJumpTarget: jumpTarget + <var: #jumpTarget type: #'void *'> + + self assert: (self addressIsInInstructions: jumpTarget)!
Item was added: + ----- Method: CogAbstractInstruction>>computeJumpTargetOffsetPlus: (in category 'generate machine code') ----- + computeJumpTargetOffsetPlus: anInteger + <inline: true> "Since it's an extraction from other methods." + | jumpTarget | + <var: #jumpTarget type: #'AbstractInstruction *'> + jumpTarget := cogit cCoerceSimple: (operands at: 0) to: #'AbstractInstruction *'. + cogit assertSaneJumpTarget: jumpTarget. + (self isAnInstruction: jumpTarget) ifTrue: + [jumpTarget := cogit cCoerceSimple: jumpTarget address to: #'AbstractInstruction *']. + self assert: jumpTarget ~= 0. + ^jumpTarget signedIntFromLong - (address + anInteger) signedIntFromLong.!
Item was changed: ----- Method: CogAbstractInstruction>>hasPCDependentInstructions (in category 'testing') ----- hasPCDependentInstructions "Answer whether the concrete machine code contains pc-dependent + instructions, such as the IA32/x86's short and long relative jumps - instructions, such as the IA32/x86's short and lopng relative jumps and the EMT64/x86-64's pc-relative addressing mode. Such instructions require an extra pass to generate them correctly." ^false!
Item was changed: ----- Method: CogIA32Compiler>>concretizeConditionalJump: (in category 'generate machine code') ----- concretizeConditionalJump: conditionCode "Will get inlined into concretizeAt: switch." "Sizing/generating jumps. Jump targets can be to absolute addresses or other abstract instructions. Generating initial trampolines instructions may have no maxSize and be to absolute addresses. Otherwise instructions must have a machineCodeSize which must be kept to." <inline: true> + | offset | - | jumpTarget offset | <var: #jumpTarget type: #'AbstractInstruction *'> + offset := self computeJumpTargetOffsetPlus: 2. - jumpTarget := cogit cCoerceSimple: (operands at: 0) to: #'AbstractInstruction *'. - cogit assertSaneJumpTarget: jumpTarget. - (self isAnInstruction: jumpTarget) ifTrue: - [jumpTarget := cogit cCoerceSimple: jumpTarget address to: #'AbstractInstruction *']. - self assert: jumpTarget ~= 0. - offset := jumpTarget signedIntFromLong - (address + 2) signedIntFromLong. (machineCodeSize = 0 "size not determined because no sizeJump pass; generating initial trampolines" ifTrue: [self isQuick: offset] ifFalse: [machineCodeSize = 2]) ifTrue: [machineCode at: 0 put: 16r70 + conditionCode; at: 1 put: (offset bitAnd: 16rFF). ^machineCodeSize := 2]. + ^self concretizeConditionalJumpLong: conditionCode! - offset := jumpTarget signedIntFromLong - (address + 6) signedIntFromLong. - machineCode - at: 0 put: 16r0F; - at: 1 put: 16r80 + conditionCode; - at: 2 put: (offset bitAnd: 16rFF); - at: 3 put: (offset >> 8 bitAnd: 16rFF); - at: 4 put: (offset >> 16 bitAnd: 16rFF); - at: 5 put: (offset >> 24 bitAnd: 16rFF). - ^machineCodeSize := 6!
Item was changed: ----- Method: CogIA32Compiler>>concretizeConditionalJumpLong: (in category 'generate machine code') ----- concretizeConditionalJumpLong: conditionCode "Will get inlined into concretizeAt: switch." "Sizing/generating jumps. Jump targets can be to absolute addresses or other abstract instructions. Generating initial trampolines instructions may have no maxSize and be to absolute addresses. Otherwise instructions must have a machineCodeSize which must be kept to." <inline: true> + | offset | + offset := self computeJumpTargetOffsetPlus: 6. - | jumpTarget offset | - <var: #jumpTarget type: #'AbstractInstruction *'> - jumpTarget := cogit cCoerceSimple: (operands at: 0) to: #'AbstractInstruction *'. - cogit assertSaneJumpTarget: jumpTarget. - (self isAnInstruction: jumpTarget) ifTrue: - [jumpTarget := cogit cCoerceSimple: jumpTarget address to: #'AbstractInstruction *']. - self assert: jumpTarget ~= 0. - offset := jumpTarget signedIntFromLong - (address + 6) signedIntFromLong. machineCode at: 0 put: 16r0F; at: 1 put: 16r80 + conditionCode; at: 2 put: (offset bitAnd: 16rFF); at: 3 put: (offset >> 8 bitAnd: 16rFF); at: 4 put: (offset >> 16 bitAnd: 16rFF); at: 5 put: (offset >> 24 bitAnd: 16rFF). ^machineCodeSize := 6!
vm-dev@lists.squeakfoundation.org