[Vm-dev] VM Maker: VMMaker.oscog-lw.260.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Jan 30 08:41:40 UTC 2013


Lars Wassermann uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-lw.260.mcz

==================== Summary ====================

Name: VMMaker.oscog-lw.260
Author: lw
Time: 30 January 2013, 9:38:08.186 am
UUID: 6ee6c419-5fb3-e34f-ac21-e2051a2076cd
Ancestors: VMMaker.oscog-eem.258

reverted all the changes done which were based on the implementation of RTLOpcode Call as (push {pc}, BL)

added abstract register LinkReg
changed trampolines as suggested on mailinglist

added assert in callTargetFromReturnAddress

=============== Diff against VMMaker.oscog-eem.258 ===============

Item was changed:
  ----- Method: CogARMCompiler>>callTargetFromReturnAddress: (in category 'inline cacheing') -----
  callTargetFromReturnAddress: callSiteReturnAddress
  	"Answer the address the call immediately preceeding callSiteReturnAddress will jump to."
  	| callDistance call |
  	call := self instructionBeforeAddress: callSiteReturnAddress.
+ 	self assert: call ~= 0. "andeq r0, r0 will not be generated, not even as nops"
  	(self isBranch: call)
  		ifTrue: [ callDistance := (call bitAnd: 16r00FFFFFF) << 2.
  			"The distance is a signed 24bit number. Therefore, the highest (26th) bit has to be expanded"
  			(callDistance bitAnd: 16r02000000) ~= 0 
  				ifTrue: [callDistance := callDistance bitOr: 16rFC000000]]
  		ifFalse: [ "A Long Jump. Extract the value saved to RISCTempReg from all the instructions before."
  			self notYetImplemented ].
  	^callSiteReturnAddress + 4 + callDistance signedIntFromLong!

Item was changed:
  ----- Method: CogARMCompiler>>computeMaximumSize (in category 'generate machine code') -----
  computeMaximumSize
  	"Because we don't use Thumb, each ARM instruction has 4 bytes. Some abstract opcodes need more than one instruction."
  	
  	| rotateableAt0then4or20Block |
  	rotateableAt0then4or20Block := [^self rotateable8bitImmediate: (operands at: 0)
  											ifTrue: [:r :i| maxSize := 4]
  											ifFalse: [maxSize := 20]].
  	
  	
  	(opcode between: FirstShortJump and: LastJump) ifTrue: [^maxSize := 16].
  	
  	opcode
  		caseOf: {
  			[Label]					-> [^maxSize := 0].
  			[AlignmentNops]		-> [^maxSize := (operands at: 0) - 1].
  			[MoveAwR]				-> [^maxSize := 16].
  			[MoveCqR]				-> [^self rotateable8bitImmediate: (operands at: 0)
  											ifTrue: [:r :i| maxSize := 4]
  											ifFalse: [maxSize := 16]].
  			[MoveCwR]				-> [^maxSize := 16].
  			[MoveRAw]				-> [^maxSize := 16].
  			[MoveRMwr]			-> [self is12BitValue: (operands at: 1)
  											ifTrue: [ :u :i | ^maxSize := 4]
  											ifFalse: [ ^maxSize := 20 ]].
  			[MoveRMbr]				-> [self is12BitValue: (operands at: 1)
  											ifTrue: [ :u :i | ^maxSize := 4]
  											ifFalse: [ ^maxSize := 20 ]].
  			[MoveMwrR]			-> [self is12BitValue: (operands at: 0)
  											ifTrue: [ :u :i | ^maxSize := 4]
  											ifFalse: [ ^maxSize := 20 ]].
  			[MoveMbrR]				-> [self is12BitValue: (operands at: 0)
  											ifTrue: [ :u :i | ^maxSize := 4]
  											ifFalse: [ ^maxSize := 20 ]].
  			[PrefetchAw] 			-> [^maxSize := 16].
+ 			[Call]					-> [^maxSize := 20 "recomputed in #sizePCDependentInstruction."].
- 			[Call]					-> [^maxSize := "<="24 "recomputed in #sizePCDependentInstruction."].
  			[RetN]					-> [^(operands at: 0) = 0 
  											ifTrue: [maxSize := 4]
  											ifFalse: [maxSize := 8]].
  			[CmpCqR]				-> [rotateableAt0then4or20Block value].
  			[AddCqR]				-> [rotateableAt0then4or20Block value].
  			[SubCqR]				-> [rotateableAt0then4or20Block value].
  			[AndCqR]				-> [rotateableAt0then4or20Block value].
  			[OrCqR]					-> [rotateableAt0then4or20Block value].
  			[XorCqR]				-> [rotateableAt0then4or20Block value].
  			[CmpCwR]				-> [^maxSize := 20].
  			[AddCwR]				-> [^maxSize := 20].
  			[SubCwR]				-> [^maxSize := 20].
  			[AndCwR]				-> [^maxSize := 20].
  			[OrCwR]				-> [^maxSize := 20].
  			[XorCwR]				-> [^maxSize := 20].
  			[JumpR]					-> [^maxSize := 4].
  			[JumpFPEqual]			-> [^maxSize := 8].
  			[JumpFPNotEqual]		-> [^maxSize := 8].
  			[JumpFPLess]			-> [^maxSize := 8].
  			[JumpFPGreaterOrEqual]-> [^maxSize := 8].
  			[JumpFPGreater]		-> [^maxSize := 8].
  			[JumpFPLessOrEqual]	-> [^maxSize := 8].
  			[JumpFPOrdered]		-> [^maxSize := 8].
  			[JumpFPUnordered]		-> [^maxSize := 8].
  			[JumpLong]				-> [^maxSize := 16].
  			[JumpLongZero]		-> [^maxSize := 16].
  			[JumpLongNonZero]	-> [^maxSize := 16].
  			[LoadEffectiveAddressMwrR] -> [rotateableAt0then4or20Block value].
  			[PushCw]				-> [^maxSize := 20].
  		}
  		otherwise: [^maxSize := 4].
  	^4 "to keep C compiler quiet"
  !

Item was changed:
  ----- Method: CogARMCompiler>>concreteRegister: (in category 'encoding') -----
  concreteRegister: registerIndex
  	 "Map a possibly abstract register into a concrete one.  Abstract registers
  	  (defined in CogAbstractOpcodes) are all negative.  If registerIndex is
  	 negative assume it is an abstract register."
  	
  	"N.B. According to BSABI, R0-R3 are caller-save, R4-R12 are callee save.
  	Note that R9 might be a special register for the implementation. In some slides it is refered to as sb. R10 can contain the stack limit (sl), R11 the fp. R12 is an intra-procedure scratch instruction pointer for link purposes. It can also be used.
  	R10 is used as temporary inside a single abstract opcode implementation"
  	"R0-R3 are used when calling back to the interpreter. Using them would require saving and restoring their values, so they are omitted so far. R12 is the only unused register at the moment.."
  	^registerIndex
  		caseOf: {
  			[TempReg]				-> [R7].
  			[ClassReg]				-> [R8].
  			[ReceiverResultReg]	-> [R9].
  			[SendNumArgsReg]		-> [R6].
  			[SPReg]					-> [SP].
  			[FPReg]					-> [R11].
  			[Arg0Reg]				-> [R4].
+ 			[Arg1Reg]				-> [R5].
+ 			[LinkReg]				-> [LR]. }
- 			[Arg1Reg]				-> [R5] }
  		otherwise:
  			[self assert: (registerIndex between: R0 and: PC).
  			 registerIndex]!

Item was changed:
  ----- Method: CogARMCompiler>>concretizeCall (in category 'generate machine code - concretize') -----
  concretizeCall
  	"Will get inlined into concretizeAt: switch."
  	<inline: true>
  	| offset |
  	self assert: (operands at: 0) ~= 0.
  	self assert: (operands at: 0) \\ 4 = 0.
+ 	offset := (operands at: 0) signedIntFromLong - (address + 8 "normal pc offset") signedIntFromLong.
- 	offset := (operands at: 0) signedIntFromLong - (address + 8 "normal pc offset" + 4 "push instruction") signedIntFromLong.
  	(self isQuick: offset)
  		ifTrue: [
+ 			self machineCodeAt: 0 put: (self t: 5 o: 8) + (offset >> 2 bitAnd: 16r00FFFFFF). "BL offset"
+ 			^machineCodeSize := 4]
- 			self machineCodeAt: 0 put: (self t: 4 o: 9 s: 0 rn: SP rd: 8 shifterOperand: 0). "push {pc}"
- 			self machineCodeAt: 4 put: (self t: 5 o: 8) + (offset >> 2 bitAnd: 16r00FFFFFF). "BL offset"
- 			^machineCodeSize := 8]
  		ifFalse: [
  			self concretizeConditionalJumpLong: AL.
  			"move the actual jump two instructions further, inserting the pc back-up to lr and the pc push."
+ 			self machineCodeAt: 16 put: (self machineCodeAt: 12).
- 			self machineCodeAt: 20 put: (self machineCodeAt: 12).
  		"Because the pc always points to the actual address + 8, the value at pc is the address of the instruction after the branch"
+ 			"mov lr, pc"
+ 			self machineCodeAt: 12 put: (self t: 0 o: 16rD s: 0 rn: 0 rd: LR shifterOperand: PC).
+ 			^machineCodeSize := 20]!
- 			"add lr, pc, #4"
- 			self machineCodeAt: 12 put: (self t: 1 o: 4 s: 0 rn: PC rd: LR shifterOperand: 4).
- 			"self machineCodeAt: 12 put: (self t: 0 o: 16rD s: 0 rn: 0 rd: LR shifterOperand: PC)."
- 			
- 			"push {pc} -- IA32 ABI, needed only for within JIT, when calling outside, like in a trampoline, maybe not."
- 			self machineCodeAt: 16 put: (self new t: 4 o: 9 s: 0 rn: SP rd: 8 shifterOperand: 0).
- 			^machineCodeSize := 24]!

Item was changed:
  ----- Method: CogARMCompiler>>isCallPreceedingReturnPC: (in category 'testing') -----
  isCallPreceedingReturnPC: mcpc
  	"Assuming mcpc is a return pc answer if the instruction before it is a call."
+ 	"There are two types of calls: BL and (MOV, ORR, ORR, ADD, ADD)"
- 	"There are two types of calls: PUSH, BL and (MOV, ORR, ORR, ADD, PUSH, ADD)"
  	"PUSH {pc} is not sufficient as a test, because pc may be pushed using the PushR opcode"
+ 	^ (objectMemory byteAt: mcpc - 3) >> 4 = 16rB "BL" 
+ 			or: [ (objectMemory longAt: mcpc - 4) >> 12 = ((self t: 1 o: 4 s: 0 rn: RISCTempReg rd: PC)"add pc, r3, 0" >> 12) ]!
- 	^(objectMemory longAt: mcpc - 8) =  (self t: 4 o: 9 s: 0 rn: SP rd: 8 shifterOperand: 0)
- 		and: [(objectMemory byteAt: mcpc - 3) >> 4 = 16rB "BL" 
- 			or: [ (objectMemory longAt: mcpc - 12) = 16rE1A0E00F "MOV pc, lr" ]]!

Item was changed:
  ----- Method: CogARMCompiler>>sizePCDependentInstructionAt: (in category 'generate machine code') -----
  sizePCDependentInstructionAt: eventualAbsoluteAddress
  	"Size a jump and set its address.  The target may be another instruction
  	 or an absolute address.  On entry the address inst var holds our virtual
  	 address. On exit address is set to eventualAbsoluteAddress, which is
  	 where this instruction will be output.  The span of a jump to a following
  	 instruction is therefore between that instruction's address and this
  	 instruction's address ((which are both still their virtual addresses), but the
  	 span of a jump to a preceeding instruction or to an absolute address is
  	 between that instruction's address (which by now is its eventual absolute
  	 address) or absolute address and eventualAbsoluteAddress."
  
  	| target maximumSpan |
  	<var: #abstractInstruction type: #'AbstractInstruction *'>
  	opcode = AlignmentNops ifTrue:
  		[| alignment |
  		 address := eventualAbsoluteAddress.
  		 alignment := operands at: 0.
  		 ^machineCodeSize := (eventualAbsoluteAddress + (alignment - 1) bitAnd: alignment negated)
  							   - eventualAbsoluteAddress].
  	self assert: (self isJump or: [opcode = Call]).
  	self isJump ifTrue: [self resolveJumpTarget].
  	target := operands at: 0.
  	"maximumSpan calculation copied from CogIA32Compiler TODO: extract method?"
  	(self isAnInstruction: (cogit cCoerceSimple: target to: #'void *'))
  		ifTrue:
  			[| abstractInstruction |
  			abstractInstruction := cogit cCoerceSimple: target to: #'AbstractInstruction *'.
  			maximumSpan := abstractInstruction address
  							- (((cogit abstractInstruction: self follows: abstractInstruction)
  								ifTrue: [eventualAbsoluteAddress]
  								ifFalse: [address]) + 2)]
  		ifFalse:
  			[maximumSpan := target - (eventualAbsoluteAddress + 2)].
  	address := eventualAbsoluteAddress.
  	^machineCodeSize := opcode = Call 
+ 				ifTrue: [(self isQuick: maximumSpan) ifTrue: [4] ifFalse: [20]]
- 				ifTrue: [(self isQuick: maximumSpan - 4 "push instruction") ifTrue: [8] ifFalse: [24]]
  				ifFalse: [(self isLongJump not and: [self isQuick: maximumSpan])
  								ifTrue: [4]
  								ifFalse: [16]] "load address to register, add"!

Item was changed:
  ----- Method: CogARMCompilerTests>>strip: (in category 'accessing') -----
  strip: aFancyDisassembledInstruction
  	"When havin an immediate > 15, the disassembler appends '	; 0x\d\d'. That is stripped."
+ 	^((aFancyDisassembledInstruction 
+ 		allButFirst: (aFancyDisassembledInstruction indexOf: $:) + 1)
+ 			copyUpTo: $;) withBlanksTrimmed!
- 	^(aFancyDisassembledInstruction copyUpTo: $;) withBlanksTrimmed!

Item was changed:
  SharedPool subclass: #CogRTLOpcodes
  	instanceVariableNames: ''
+ 	classVariableNames: 'AddCqR AddCwR AddRR AddRdRd AlignmentNops AndCqR AndCwR AndRR Arg0Reg Arg1Reg ArithmeticShiftRightCqR ArithmeticShiftRightRR Call ClassReg CmpCqR CmpCwR CmpRR CmpRdRd ConvertRRd DPFPReg0 DPFPReg1 DPFPReg2 DPFPReg3 DPFPReg4 DPFPReg5 DPFPReg6 DPFPReg7 DivRdRd FPReg Fill16 Fill32 Fill8 FillBytesFrom FillFromWord FirstJump FirstShortJump GPRegMax GPRegMin Jump JumpAbove JumpAboveOrEqual JumpBelow JumpBelowOrEqual JumpCarry JumpFPEqual JumpFPGreater JumpFPGreaterOrEqual JumpFPLess JumpFPLessOrEqual JumpFPNotEqual JumpFPOrdered JumpFPUnordered JumpGreater JumpGreaterOrEqual JumpLess JumpLessOrEqual JumpLong JumpLongNonZero JumpLongZero JumpNegative JumpNoCarry JumpNoOverflow JumpNonNegative JumpNonZero JumpOverflow JumpR JumpZero Label LastJump LastRTLCode LinkReg LoadEffectiveAddressMwrR LogicalShiftLeftCqR LogicalShiftLeftRR LogicalShiftRightCqR LogicalShiftRightRR MoveAbR MoveAwR MoveC32R MoveC64R MoveCqR MoveCwR MoveM16rR MoveM64rRd MoveMbrR MoveMwrR MoveRAw MoveRM16r MoveRMbr MoveRMwr MoveRR MoveRX16rR MoveRXbrR MoveRXwrR MoveRdM64r MoveRdRd MoveX16rRR MoveXbrRR MoveXwrRR MulCqR MulCwR MulRR MulRdRd NegateR Nop OrCqR OrCwR OrRR PopR PrefetchAw PushCw PushR ReceiverResultReg RetN SPReg SendNumArgsReg SqrtRd SubCqR SubCwR SubRR SubRdRd TempReg XorCqR XorCwR XorRR'
- 	classVariableNames: 'AddCqR AddCwR AddRR AddRdRd AlignmentNops AndCqR AndCwR AndRR Arg0Reg Arg1Reg ArithmeticShiftRightCqR ArithmeticShiftRightRR Call ClassReg CmpCqR CmpCwR CmpRR CmpRdRd ConvertRRd DPFPReg0 DPFPReg1 DPFPReg2 DPFPReg3 DPFPReg4 DPFPReg5 DPFPReg6 DPFPReg7 DivRdRd FPReg Fill16 Fill32 Fill8 FillBytesFrom FillFromWord FirstJump FirstShortJump GPRegMax GPRegMin Jump JumpAbove JumpAboveOrEqual JumpBelow JumpBelowOrEqual JumpCarry JumpFPEqual JumpFPGreater JumpFPGreaterOrEqual JumpFPLess JumpFPLessOrEqual JumpFPNotEqual JumpFPOrdered JumpFPUnordered JumpGreater JumpGreaterOrEqual JumpLess JumpLessOrEqual JumpLong JumpLongNonZero JumpLongZero JumpNegative JumpNoCarry JumpNoOverflow JumpNonNegative JumpNonZero JumpOverflow JumpR JumpZero Label LastJump LastRTLCode LoadEffectiveAddressMwrR LogicalShiftLeftCqR LogicalShiftLeftRR LogicalShiftRightCqR LogicalShiftRightRR MoveAbR MoveAwR MoveC32R MoveC64R MoveCqR MoveCwR MoveM16rR MoveM64rRd MoveMbrR MoveMwrR MoveRAw MoveRM16r MoveRMbr MoveRMwr MoveRR MoveRX16rR MoveRXbrR MoveRXwrR MoveRdM64r MoveRdRd MoveX16rRR MoveXbrRR MoveXwrRR MulCqR MulCwR MulRR MulRdRd NegateR Nop OrCqR OrCwR OrRR PopR PrefetchAw PushCw PushR ReceiverResultReg RetN SPReg SendNumArgsReg SqrtRd SubCqR SubCwR SubRR SubRdRd TempReg XorCqR XorCwR XorRR'
  	poolDictionaries: ''
  	category: 'VMMaker-JIT'!
  
  !CogRTLOpcodes commentStamp: '<historical>' prior: 0!
  I am a pool for the Register-Transfer-Language to which Cog compiles.  I define unique integer values for all RTL opcodes and abstract registers.  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.
  	 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 operand specifiers are
  		R - general purpose 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 with an absolute address
  		Ab    - memory byte with 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
  		M16r  - memory 16-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
  		XbrR- memory word whose address is r * byte size away from an address in a register
  		X16rR- memory word whose address is r * (2 bytes size) away from an address in a register
  		XwrR- memory word whose address is r * word size away from an address in a register
  
  	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 instrucions
  	leave the condition codes unaffected.  In particular LoadEffectiveAddressMwrR does not set condition codes
  	although it can be used to do arithmetic.
  
  	Note that there are no generic division instructions defined, but a processor may define some."
  
  	"CogRTLOpcodes initialize.
  	 CogAbstractInstruction allSubclasses do: [:sc| sc initialize]"
  
  	| opcodeNames refs |
  	FPReg := -1.
  	SPReg := -2.
  	ReceiverResultReg := GPRegMax := -3.
  	TempReg := -4.
  	ClassReg := -5.
  	SendNumArgsReg := -6.
  	Arg0Reg := -7.
  	Arg1Reg := GPRegMin := -8.
  
  	DPFPReg0 := -9.
  	DPFPReg1 := -10.
  	DPFPReg2 := -11.
  	DPFPReg3 := -12.
  	DPFPReg4 := -13.
  	DPFPReg5 := -14.
  	DPFPReg6 := -15.
  	DPFPReg7 := -16.
+ 	
+ 	LinkReg := -17.
  
  	opcodeNames := #("Noops & Pseudo Ops"
  						Label
  						AlignmentNops
  						FillBytesFrom	"output operand 0's worth of bytes from the address in operand 1"
  						Fill8				"output a byte's worth of bytes with operand 0"
  						Fill16			"output two byte's worth of bytes with operand 0"
  						Fill32			"output four byte's worth of bytes with operand 0"
  						FillFromWord	"output BytesPerWord's worth of bytes with operand 0 + operand 1"
  						Nop
  
  						"Control"
  						Call
  						RetN
  						JumpR				"Not a regular jump, i.e. not pc dependent."
  
  						"N.B.  Jumps are contiguous.  Long jumps are contigiuous within them.  See FirstJump et al below"
  						JumpLong
  						JumpLongZero		"a.k.a. JumpLongEqual"
  						JumpLongNonZero	"a.k.a. JumpLongNotEqual"
  						Jump
  						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
  						MoveRAw
  						MoveAbR
  						MoveMwrR MoveRMwr MoveXwrRR MoveRXwrR
  						MoveM16rR MoveRM16r MoveX16rRR MoveRX16rR
  						MoveMbrR MoveRMbr MoveXbrRR MoveRXbrR
  						MoveCqR MoveCwR MoveC32R MoveC64R
  						MoveRdRd MoveM64rRd MoveRdM64r
  						PopR PushR PushCw
  						PrefetchAw
  
  						"Arithmetic; destination is always last operand except Cmp; CmpXR is SubRX with no update of result"
  						LoadEffectiveAddressMwrR "A variant of add"
  						NegateR "2's complement negation"
  						ArithmeticShiftRightCqR ArithmeticShiftRightRR
  						LogicalShiftRightCqR LogicalShiftRightRR
  						LogicalShiftLeftCqR LogicalShiftLeftRR
  
  						CmpRR AddRR SubRR AndRR OrRR XorRR MulRR
  						CmpCqR AddCqR SubCqR AndCqR OrCqR XorCqR MulCqR
  						CmpCwR AddCwR SubCwR AndCwR OrCwR XorCwR MulCwR
  
  						CmpRdRd AddRdRd SubRdRd MulRdRd DivRdRd SqrtRd
  
  						"Conversion"
  						ConvertRRd
  
  						LastRTLCode).
  
  	refs := (thisContext method literals select: [:l| l isVariableBinding and: [classPool includesKey: l key]]) collect:
  				[:ea| ea key].
  	(classPool keys reject: [:k| (opcodeNames includes: k) or: [refs includes: k]]) do:
  		[:k|
  		Undeclared declare: k from: classPool].
  	opcodeNames withIndexDo:
  		[:classVarName :value|
  		self classPool
  			declare: classVarName from: Undeclared;
  			at: classVarName put: value].
  	FirstJump := JumpLong.
  	LastJump := JumpFPUnordered.
  	FirstShortJump := Jump!

Item was changed:
  ----- Method: CogRTLOpcodes class>>nameForAbstractRegister: (in category 'debug printing') -----
  nameForAbstractRegister: reg "<Integer>"
  	^#(Arg0Reg Arg1Reg ClassReg FPReg ReceiverResultReg SPReg SendNumArgsReg TempReg
+ 		DPFPReg0 DPFPReg1 DPFPReg2 DPFPReg3 DPFPReg4 DPFPReg5 DPFPReg6 DPFPReg7 LinkReg)
- 		DPFPReg0 DPFPReg1 DPFPReg2 DPFPReg3 DPFPReg4 DPFPReg5 DPFPReg6 DPFPReg7)
  			detect: [:sym| (classPool at: sym) = reg]!

Item was changed:
  ----- Method: CogRTLOpcodes class>>nameForRegister: (in category 'debug printing') -----
  nameForRegister: reg "<Integer>"
  	^#(Arg0Reg Arg1Reg ClassReg FPReg ReceiverResultReg SPReg SendNumArgsReg TempReg
+ 		DPFPReg0 DPFPReg1 DPFPReg2 DPFPReg3 DPFPReg4 DPFPReg5 DPFPReg6 DPFPReg7 LinkReg)
- 		DPFPReg0 DPFPReg1 DPFPReg2 DPFPReg3 DPFPReg4 DPFPReg5 DPFPReg6 DPFPReg7)
  			detect: [:sym| (classPool at: sym) = reg]!

Item was changed:
  ----- Method: Cogit>>compileAbort (in category 'compile abstract instructions') -----
  compileAbort
  	"The start of a CogMethod has a call to a run-time abort routine that either
  	 handles an in-line cache failure or a stack overflow.  The routine selects the
  	 path depending on ReceiverResultReg; if zero it takes the stack overflow
  	 path; if nonzero the in-line cache miss path.  Neither of these paths returns.
  	 The abort routine must be called;  In the callee the method is located by
  	 adding the relevant offset to the return address of the call."
  	stackOverflowCall := self MoveCq: 0 R: ReceiverResultReg.
+ 	backEnd hasLinkRegister ifTrue:
+ 		[self PushR: LinkReg].
  	sendMissCall := self Call: (self methodAbortTrampolineFor: methodOrBlockNumArgs)!

Item was changed:
  ----- Method: Cogit>>compileTrampolineFor:callJumpBar:numArgs:arg:arg:arg:arg:saveRegs:resultReg: (in category 'initialization') -----
  compileTrampolineFor: aRoutine callJumpBar: callJumpBar "<Boolean>" numArgs: numArgs arg: regOrConst0 arg: regOrConst1 arg: regOrConst2 arg: regOrConst3 saveRegs: saveRegs resultReg: resultRegOrNil
  	"Generate a trampoline with up to four arguments.  Generate either a call or a jump to aRoutine
  	 as requested by callJumpBar.  If generating a call and resultRegOrNil is non-zero pass the C result
  	 back in resultRegOrNil.
  	 Hack: a negative value indicates an abstract register, a non-negative value indicates a constant."
  	<var: #aRoutine type: #'void *'>
  	<inline: false>
  	self genSaveStackPointers.
  	self genLoadCStackPointers.
  	cStackAlignment > BytesPerWord ifTrue:
  		[backEnd
  			genAlignCStackSavingRegisters: saveRegs
  			numArgs: numArgs
  			wordAlignment: cStackAlignment / BytesPerWord].
  	saveRegs ifTrue:
  		[callJumpBar ifFalse:
  			[self error: 'why save registers when you''re not going to return?'].
  		 backEnd genSaveRegisters].
  	numArgs > 0 ifTrue:
  		[numArgs > 1 ifTrue:
  			[numArgs > 2 ifTrue:
  				[numArgs > 3 ifTrue:
  					[regOrConst3 < 0
  						ifTrue: [backEnd genPassReg: regOrConst3 asArgument: 3]
  						ifFalse: [backEnd genPassConst: regOrConst3 asArgument: 3]].
  				 regOrConst2 < 0
  					ifTrue: [backEnd genPassReg: regOrConst2 asArgument: 2]
  					ifFalse: [backEnd genPassConst: regOrConst2 asArgument: 2]].
  			regOrConst1 < 0
  				ifTrue: [backEnd genPassReg: regOrConst1 asArgument: 1]
  				ifFalse: [backEnd genPassConst: regOrConst1 asArgument: 1]].
  		regOrConst0 < 0
  			ifTrue: [backEnd genPassReg: regOrConst0 asArgument: 0]
  			ifFalse: [backEnd genPassConst: regOrConst0 asArgument: 0]].
+ 	backEnd hasLinkRegister 
+ 		ifTrue: [self gen: PushR operand: LinkReg].
  	self gen: (callJumpBar ifTrue: [Call] ifFalse: [Jump])
  		operand: (self cCode: [aRoutine asUnsignedInteger]
  					   inSmalltalk: [self simulatedTrampolineFor: aRoutine]).
  	callJumpBar ifTrue:
  		[resultRegOrNil ifNotNil:
  			[backEnd genWriteCResultIntoReg: resultRegOrNil].
  		 saveRegs ifTrue:
  			[numArgs > 0 ifTrue:
  				[backEnd genRemoveNArgsFromStack: numArgs].
  			resultRegOrNil
  				ifNotNil: [backEnd genRestoreRegsExcept: resultRegOrNil]
  				ifNil: [backEnd genRestoreRegs]].
  		self genLoadStackPointers.
  		self RetN: 0]!

Item was changed:
  ----- Method: Cogit>>genMethodAbortTrampoline (in category 'initialization') -----
  genMethodAbortTrampoline
  	"Generate the abort for a method.  This abort performs either a call of ceSICMiss:
  	 to handle a single-in-line cache miss or a call of ceStackOverflow: to handle a
  	 stack overflow.  It distinguishes the two by testing ResultReceiverReg.  If the
  	 register is zero then this is a stack-overflow because a) the receiver has already
  	 been pushed and so can be set to zero before calling the abort, and b) the
  	 receiver must always contain an object (and hence be non-zero) on SIC miss."
  	| jumpSICMiss |
  	<var: #jumpSICMiss type: #'AbstractInstruction *'>
  	opcodeIndex := 0.
  	self CmpCq: 0 R: ReceiverResultReg.
  	jumpSICMiss := self JumpNonZero: 0.
+ 	backEnd hasLinkRegister 
+ 		ifTrue: [self MoveR: LinkReg Mw: 0 r: SPReg]. "overwrite send ret address with ceMethodAbortTrampoline call ret address"
  	self compileTrampolineFor: #ceStackOverflow:
  		callJumpBar: true
  		numArgs: 1
  		arg: SendNumArgsReg
  		arg: nil
  		arg: nil
  		arg: nil
  		saveRegs: false
  		resultReg: nil.
  	jumpSICMiss jmpTarget: self Label.
+ 	backEnd hasLinkRegister 
+ 		ifTrue: [self PushR: LinkReg]. "push ret address for ceMethodAbortTrampoline call"
  	^self genTrampolineFor: #ceSICMiss:
  		called: 'ceMethodAbort'
  		callJumpBar: true
  		numArgs: 1
  		arg: ReceiverResultReg
  		arg: nil
  		arg: nil
  		arg: nil
  		saveRegs: false
  		resultReg: nil
  		appendOpcodes: true!

Item was changed:
  ----- Method: VMMaker class>>generateSqueakCogVM (in category 'configurations') -----
  generateSqueakCogVM
  	^VMMaker
  		generate: (Smalltalk at: ([:choices| choices at: (UIManager default chooseFrom: choices) ifAbsent: [^self]]
  									value: #(CoInterpreter CoInterpreterMT)))
  		and: StackToRegisterMappingCogit
  		with: #(	MULTIPLEBYTECODESETS false
  				NewspeakVM false)
  		to: (FileDirectory default pathFromURI: 'oscogvm/src')
  		platformDir: (FileDirectory default pathFromURI: 'oscogvm/platforms')
  		including:#(	ADPCMCodecPlugin AsynchFilePlugin BalloonEnginePlugin B3DAcceleratorPlugin
+ 					BMPReadWriterPlugin BitBltSimulation BochsIA32Plugin CroquetPlugin DSAPlugin
- 					BMPReadWriterPlugin BitBltSimulation BochsIA32Plugin GdbARMPlugin CroquetPlugin DSAPlugin
  					DeflatePlugin DropPlugin FT2Plugin FFTPlugin FileCopyPlugin FilePlugin FloatArrayPlugin
  					FloatMathPlugin GeniePlugin HostWindowPlugin IA32ABIPlugin InternetConfigPlugin
  					JPEGReadWriter2Plugin JPEGReaderPlugin JoystickTabletPlugin KlattSynthesizerPlugin
  					LargeIntegersPlugin LocalePlugin MIDIPlugin MacMenubarPlugin Matrix2x3Plugin
  					MiscPrimitivePlugin Mpeg3Plugin QuicktimePlugin RePlugin SecurityPlugin SerialPlugin
  					SocketPlugin SoundCodecPlugin SoundGenerationPlugin SoundPlugin ThreadedIA32FFIPlugin
  					StarSqueakPlugin UUIDPlugin UnixOSProcessPlugin Win32OSProcessPlugin VMProfileMacSupportPlugin)!



More information about the Vm-dev mailing list