[Vm-dev] VM Maker: VMMaker.oscog-eem.2605.mcz

commits at source.squeak.org commits at source.squeak.org
Sun Dec 8 21:43:42 UTC 2019


Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2605.mcz

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

Name: VMMaker.oscog-eem.2605
Author: eem
Time: 8 December 2019, 1:43:34.017439 pm
UUID: 672f397d-4817-45b7-ae80-098edcf9a37f
Ancestors: VMMaker.oscog-eem.2604

A64 XwrRR, NegateR, SubRR.
Document that arithmetic sets carry/borrow but does not respond to it.

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

Item was added:
+ ----- Method: CogARMv8Compiler>>concretizeDataOperationRR: (in category 'generate machine code - concretize') -----
+ concretizeDataOperationRR: opcode
+ 	"C3.4	Data processing - register	C3-219
+ 
+ 	- Arithmetic (shifted register).
+ 	- Arithmetic (extended register) on page C3-220.
+ 	- Arithmetic with carry on page C3-221.
+ 	- Flag manipulation instructions on page C3-221.
+ 	- Logical (shifted register) on page C3-221.
+ 	- Move (register) on page C3-222.
+ 	- Shift (register) on page C3-222.
+ 	- Multiply and divide on page C3-223.
+ 	- CRC32 on page C3-224.
+ 	- Bit operation on page C3-225.
+ 	- Conditional select on page C3-225.
+ 	- Conditional comparison on page C3-226."
+ 
+ 	"C3.4.2		Arithmetic (extended register)
+ 
+ 	The extended register instructions provide an optional sign-extension or zero-extension of a portion of the second source register value,
+ 	 followed by an optional left shift by a constant amount of 1-4, inclusive.
+ 		ADD (extended register) on page C6-758
+ 		ADDS (extended register) on page C6-766
+ 		SUB (extended register) on page C6-1308
+ 		SUBS (extended register) on page C6-1318
+ 		CMN (extended register) on page C6-850
+ 		CMP (extended register) on page C6-856"
+ 
+ 	self shouldNotImplement!

Item was added:
+ ----- Method: CogARMv8Compiler>>concretizeMoveXwrRR (in category 'generate machine code - concretize') -----
+ concretizeMoveXwrRR
+ 	"Xwr - memory word whose address is r * word size away from an address in a register"
+ 	"C6.2.132	LDR (register)	C6-981"
+ 	| destReg srcReg |
+ 	srcReg := operands at: 0.
+ 	destReg := operands at: 1.
+ 	self deny: SP = destReg.
+ 	machineCode
+ 		at: 0
+ 		put: 2r11111000011 << 21
+ 			+ (destReg << 16)
+ 			+ (UXTX << 13)
+ 			+ (1 << 12)
+ 			+ (srcReg << 5)
+ 			+ destReg.
+ 	^machineCodeSize := 4!

Item was added:
+ ----- Method: CogARMv8Compiler>>concretizeNegateR (in category 'generate machine code - concretize') -----
+ concretizeNegateR
+ 	"C6.2.313	SUBS (extended register)	C6-1318"
+ 	| reg |
+ 	reg := operands at: 0.
+ 	self deny: SP = reg.
+ 	machineCode
+ 		at: 0
+ 		put: 2r11101011001 << 21
+ 			+ (31 << 16)
+ 			+ (UXTX << 13)
+ 			+ (reg << 5)
+ 			+ reg.
+ 	^machineCodeSize := 4!

Item was added:
+ ----- Method: CogARMv8Compiler>>concretizeSubRR (in category 'generate machine code - concretize') -----
+ concretizeSubRR
+ 	"C6.2.313	SUBS (extended register)	C6-1318"
+ 	| destReg srcReg |
+ 	srcReg := operands at: 0.
+ 	destReg := operands at: 1.
+ 	self deny: SP = destReg.
+ 	machineCode
+ 		at: 0
+ 		put: 2r11101011001 << 21
+ 			+ (destReg << 16)
+ 			+ (UXTX << 13)
+ 			+ (srcReg << 5)
+ 			+ destReg.
+ 	^machineCodeSize := 4!

Item was changed:
  ----- Method: CogARMv8Compiler>>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."
  	<returnTypeC: #void>
  		 
  	opcode caseOf: {
  		"Noops & Pseudo Ops"
  		[Label]					-> [^self concretizeLabel].
  		[Literal]					-> [^self concretizeLiteral].
  		[AlignmentNops]		-> [^self concretizeAlignmentNops].
  		[Fill32]					-> [^self concretizeFill32].
  		[Nop]					-> [^self concretizeNop].
  		"Control"
  		[Call]						-> [^self concretizeCall]. "call code within code space"
  		[CallFull]					-> [^self concretizeCallFull]. "call code anywhere in address space"
  		[JumpR]					-> [^self concretizeJumpR].
  		[JumpFull]					-> [^self concretizeJumpFull]."jump within address space"
  		[JumpLong]				-> [^self concretizeConditionalJump: AL]."jumps witihn code space"
  		[JumpLongZero]			-> [^self concretizeConditionalJump: EQ].
  		[JumpLongNonZero]		-> [^self concretizeConditionalJump: 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: CC]. "unsigned lower"
  		[JumpAboveOrEqual]		-> [^self concretizeConditionalJump: CS]. "unsigned greater or equal"
  		[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].
  		[Stop]						-> [^self concretizeStop].
  		"Arithmetic"
  		[AddCqR]						-> [^self concretizeAddCqR].
  		[AndCqR]						-> [^self concretizeInvertibleDataOperationCqR: AndOpcode].
  		[AndCqRR]						-> [^self concretizeAndCqRDest: (operands at: 1)].
  		[CmpCqR]						-> [^self concretizeCmpCqR].
  		[OrCqR]						-> [^self concretizeDataOperationCqR: OrOpcode].
  		[SubCqR]						-> [^self concretizeSubCqR].
  		[TstCqR]						-> [^self concretizeAndCqRDest: XZR].
  		[XorCqR]						-> [^self concretizeInvertibleDataOperationCqR: XorOpcode].
  		[AddCwR]						-> [^self concretizeDataOperationCwR: AddOpcode].
  		[AndCwR]						-> [^self concretizeDataOperationCwR: AndOpcode].
  		[CmpCwR]						-> [^self concretizeDataOperationCwR: CmpOpcode].
  		[OrCwR]						-> [^self concretizeDataOperationCwR: OrOpcode].
  		[SubCwR]						-> [^self concretizeDataOperationCwR: SubOpcode].
  		[XorCwR]						-> [^self concretizeDataOperationCwR: XorOpcode].
+ 		[AddRR]						-> [^self concretizeAddRR].
- 		[AddRR]						-> [^self concretizeDataOperationRR: AddOpcode].
  		[AndRR]						-> [^self concretizeDataOperationRR: AndOpcode].
  		[CmpRR]						-> [^self concretizeDataOperationRR: CmpOpcode].
  		[OrRR]							-> [^self concretizeDataOperationRR: OrOpcode].
+ 		[SubRR]						-> [^self concretizeSubRR].
- 		[SubRR]						-> [^self concretizeDataOperationRR: SubOpcode].
  		[XorRR]							-> [^self concretizeDataOperationRR: XorOpcode].
  		[AddRdRd]						-> [^self concretizeAddRdRd].
  		[CmpRdRd]						-> [^self concretizeCmpRdRd].
  		[DivRdRd]						-> [^self concretizeDivRdRd].
  		[MulRdRd]						-> [^self concretizeMulRdRd].
  		[SubRdRd]						-> [^self concretizeSubRdRd].
  		[SqrtRd]						-> [^self concretizeSqrtRd].
  		[NegateR]						-> [^self concretizeNegateR].
  		[LoadEffectiveAddressMwrR]	-> [^self concretizeLoadEffectiveAddressMwrR].
  		[ArithmeticShiftRightCqR]		-> [^self concretizeArithmeticShiftRightCqR].
  		[LogicalShiftRightCqR]			-> [^self concretizeLogicalShiftRightCqR].
  		[LogicalShiftLeftCqR]			-> [^self concretizeLogicalShiftLeftCqR].
  		[ArithmeticShiftRightRR]		-> [^self concretizeArithmeticShiftRightRR].
  		[LogicalShiftLeftRR]				-> [^self concretizeLogicalShiftLeftRR].
  		[LogicalShiftRightRR]			-> [^self concretizeLogicalShiftRightRR].
  		[ClzRR]							-> [^self concretizeClzRR].
  		"Data Movement"
  		[MoveCqR]			-> [^self concretizeMoveCqR].
  		[MoveCwR]			-> [^self concretizeMoveCwR].
  		[MoveRR]			-> [^self concretizeMoveRR].
  		[MoveAwR]			-> [^self concretizeMoveAwR].
  		[MoveRAw]			-> [^self concretizeMoveRAw].
  		[MoveAbR] 			-> [^self concretizeMoveAbR].
   		[MoveRAb]			-> [^self concretizeMoveRAb].
  		[MoveMbrR]		-> [^self concretizeMoveMbrR].
  		[MoveRMbr]		-> [^self concretizeMoveRMbr].
  		[MoveRM16r]		-> [^self concretizeMoveRM16r].
  		[MoveM16rR]		-> [^self concretizeMoveM16rR].
  		[MoveM64rRd]		-> [^self concretizeMoveM64rRd].
  		[MoveMwrR]		-> [^self concretizeMoveMwrR].
  		[MoveXbrRR]		-> [^self concretizeMoveXbrRR].
  		[MoveRXbrR]		-> [^self concretizeMoveRXbrR].
  		[MoveXwrRR]		-> [^self concretizeMoveXwrRR].
  		[MoveRXwrR]		-> [^self concretizeMoveRXwrR].
  		[MoveRMwr]		-> [^self concretizeMoveRMwr].
  		[MoveRdM64r]		-> [^self concretizeMoveRdM64r].
  		[PopR]				-> [^self concretizePopR].
  		[PushR]				-> [^self concretizePushR].
  		[PushCq]			-> [^self concretizePushCq].
  		[PushCw]			-> [^self concretizePushCw].
  		[PrefetchAw]		-> [^self concretizePrefetchAw].
  		"Conversion"
  		[ConvertRRd]		-> [^self concretizeConvertRRd].
  		[ConvertRdR]		-> [^self concretizeConvertRdR].
  		[ConvertRRs]		-> [^self concretizeConvertRRs].
  		[ConvertRsR]		-> [^self concretizeConvertRsR].
  		[ConvertRsRd]		-> [^self concretizeConvertRsRd].
  		[ConvertRdRs]		-> [^self concretizeConvertRdRs].
  			
  		[SignExtend8RR]	-> [^self concretizeSignExtend8RR].
  		[SignExtend16RR]	-> [^self concretizeSignExtend16RR].
  		[SignExtend32RR]	-> [^self concretizeSignExtend32RR].
  		
  		[ZeroExtend8RR]	-> [^self concretizeZeroExtend8RR].
  		[ZeroExtend16RR]	-> [^self concretizeZeroExtend16RR].
  		[ZeroExtend32RR]	-> [^self concretizeZeroExtend32RR].}!

Item was changed:
  ----- Method: CogRTLOpcodes class>>initialize (in category 'class initialization') -----
  initialize
  	"Abstract opcodes are a compound of a one word operation specifier and zero or more operand type specifiers.
  	 The assembler is in Cogit protocol abstract instructions and uses `at&t' syntax, assigning to the register on the
  	 right. e.g. MoveRR is the Move opcode with two register operand specifiers and defines a move register to
  	 register instruction from operand 0 to operand 1.  The word and register size is assumed to be either 32-bits
  	 on a 32-bit architecture or 64-bits on a 64-bit architecture.  The abstract machine is mostly a 2 address machine
  	 with the odd three address instruction added to better exploit RISCs.
  			(self initialize)
  	The operand specifiers are
  		R		- general purpose register
  		Rs		- single-precision floating-point register
  		Rd		- double-precision floating-point register
  		Cq		- a `quick' constant that can be encoded in the minimum space possible.
  		Cw		- a constant with word size where word is the default operand size for the Smalltalk VM, 32-bits
  				  for a 32-bit VM, 64-bits for a 64-bit VM.  The generated constant must occupy the default number
  				  of bits.  This allows e.g. a garbage collector to update the value without invalidating the code.
  		C32	- a constant with 32 bit size.  The generated constant must occupy 32 bits.
  		C64	- a constant with 64 bit size.  The generated constant must occupy 64 bits.
  		Aw		- memory word (32-bits for a 32-bit VM, 64-bits for a 64-bit VM) at an absolute address
  				  See note about MoveAwR and MoveRAw in the opcodeNames literal array below!!!!
  		Ab		- memory byte at an absolute address
  		A32	- memory 32-bit halfword at an absolute address
  		Mwr	- memory word whose address is at a constant offset from an address in a register
  		Mbr		- memory byte whose address is at a constant offset from an address in a register (zero-extended on read)
  		M16r	- memory 16-bit halfword whose address is at a constant offset from an address in a register
  		M32r	- memory 32-bit halfword whose address is at a constant offset from an address in a register
  		M64r	- memory 64-bit doubleword whose address is at a constant offset from an address in a register
  		Xbr		- memory byte whose address is r * byte size away from an address in a register
  		X16r	- memory 16-bit halfword whose address is r * (2 bytes size) away from an address in a register
  		X32r	- memory 32-bit halfword whose address is r * (4 bytes size) away from an address in a register (64-bit ISAs only)
  		Xwr		- memory word whose address is r * word size away from an address in a register
  		Xowr	- memory word whose address is o + (r * word size) away from an address in a register (scaled indexed)
  
  	An alternative would be to decouple opcodes from operands, e.g.
  		Move := 1. Add := 2. Sub := 3...
  		RegisterOperand := 1. ConstantQuickOperand := 2. ConstantWordOperand := 3...
  	But not all combinations make sense and even fewer are used so we stick with the simple compound approach.
  
  	The assumption is that comparison and arithmetic instructions set condition codes and that move instructions
  	leave the condition codes unaffected.  In particular LoadEffectiveAddressMwrR does not set condition codes
  	although it can be used to do arithmetic.  On processors such as MIPS this distinction is invalid; there are no
  	condition codes.  So the backend is allowed to collapse operation, branch pairs to internal instruction definitions
+ 	(see senders and implementors of noteFollowingConditionalBranch:).
+ 	We also assume that arithmetic sets the carry flag but that Add?R/Sub?R et al ignore the carry flag as a source operand.
+ 	This is because multiple precision arithmetic is implem ented in plugins (LargeIntegerPlugins) and hence not (yet)
+ 	important here.
- 	(see senders and implementors of noteFollowingConditionalBranch:). 
  
  	Not all of the definitions in opcodeDefinitions below are implemented.  In particular we do not implement the
  	XowrR scaled index addressing mode since it requires 4 operands.
  
  	Not all instructions make sense on all architectures.  MoveRRd and MoveRdR are meaningful only on 64-bit machines.
  
  	Note that there are no generic division instructions defined, but a processor may define some.
  
  	Branch/Call ranges.  Jump[Cond] can be generated as short as possible.  Call/Jump[Cond]Long must be generated
  	in the same number of bytes irrespective of displacement since their targets may be updated, but they need only
  	span 16Mb, the maximum size of the code zone.  This allows e.g. ARM to use single-word call and jump instructions
  	for most calls and jumps.  CallFull/JumpFull must also be generated in the same number of bytes irrespective of
  	displacement for the same reason, but they must be able to span the full (32-bit or 64-bit) address space because
  	they are used to call code in the C runtime, which may be distant from the code zone.  CallFull/JumpFull are allowed
  	to use the cResultRegister as a scratch if required (e.g. on x64 where there is no direct 64-bit call or jump).
  
  	Byte reads.  If the concrete compiler class answers true to byteReadsZeroExtend then byte reads must zero-extend
  	the byte read into the destination register.  If not, the other bits of the register should be left undisturbed and the
  	Cogit will add an instruction to zero the register as required.  Under no circumstances should byte reads sign-extend.
  
  	16-bit (and on 64-bits, 32-bit) reads.  These /are/ expected to always zero-extend."
  
  	| opcodeNames refs |
  	opcodeNames := #("Noops & Pseudo Ops"
  						Label
  						Literal			"a word-sized literal"
  						AlignmentNops
  						Fill32			"output four byte's worth of bytes with operand 0"
  						Nop
  
  						"Control"
  						Call					"call within the code zone"
  						CallFull				"call anywhere within the full address space"
  						CallR
  						RetN
  						JumpR				"Not a regular jump, i.e. not pc dependent."
  						Stop				"Halt the processor"
  
  						"N.B.  Jumps are contiguous.  Long and Full jumps are contiguous within them.  See FirstJump et al below"
  						JumpFull			"Jump anywhere within the address space"
  						JumpLong			"Jump anywhere within the 16mb code zone."
  						JumpLongZero			"a.k.a. JumpLongEqual"
  						JumpLongNonZero		"a.k.a. JumpLongNotEqual"
  						Jump				"short jumps; can be encoded in as few bytes as possible; will not be disturbed by GC or relocation."
  						JumpZero				"a.k.a. JumpEqual"
  						JumpNonZero			"a.k.a. JumpNotEqual"
  						JumpNegative
  						JumpNonNegative
  						JumpOverflow
  						JumpNoOverflow
  						JumpCarry
  						JumpNoCarry
  						JumpLess			"signed"
  						JumpGreaterOrEqual
  						JumpGreater
  						JumpLessOrEqual
  						JumpBelow			"unsigned"
  						JumpAboveOrEqual
  						JumpAbove
  						JumpBelowOrEqual
  
  						JumpFPEqual
  						JumpFPNotEqual
  						JumpFPLess
  						JumpFPLessOrEqual
  						JumpFPGreater
  						JumpFPGreaterOrEqual
  						JumpFPOrdered
  						JumpFPUnordered
  
  						"Data Movement; destination is always last operand"
  						MoveRR
  						"N.B. On certain targets (including X64) MoveAwR & MoveRAw may
  						 smash TempReg if the register argument is either FPReg or SPReg!!!!"
  						MoveAwR MoveA32R
  						MoveRAw MoveRA32
  						MoveAbR
  						MoveRAb
  						MoveMwrR MoveRMwr MoveXwrRR MoveRXwrR "MoveXowrR MoveRXowr""Unused"
  						MoveM8rR MoveMs8rR MoveRM8r 
  						MoveM16rR MoveRM16r MoveX16rRR MoveRX16rR
  						MoveM32rR MoveRM32r MoveX32rRR MoveRX32rR
  						MoveMbrR MoveRMbr MoveXbrRR MoveRXbrR
  						MoveCqR MoveCwR MoveC32R "MoveC64R""Not used"
  						MoveRRd MoveRdR MoveRdRd MoveM64rRd MoveRdM64r
  						MoveRsRs MoveM32rRs MoveRsM32r
  						PopR PushR PushCq PushCw
  						PrefetchAw
  
  						"Arithmetic; destination is always last operand except Cmp; CmpXR is SubRX with no update of result"
  						LoadEffectiveAddressMwrR "LoadEffectiveAddressXowrR" "Variants of add/multiply"
  						NegateR "2's complement negation"
  						NotR
  						ArithmeticShiftRightCqR ArithmeticShiftRightRR
  						LogicalShiftRightCqR LogicalShiftRightRR
  						LogicalShiftLeftCqR LogicalShiftLeftRR
  						RotateLeftCqR RotateRightCqR
  
  						CmpRR AddRR SubRR AndRR OrRR XorRR
  						CmpCqR AddCqR SubCqR AndCqR OrCqR TstCqR XorCqR
  						CmpCwR CmpC32R AddCwR SubCwR AndCwR OrCwR XorCwR
  						AddcRR AddcCqR SubbRR SubbCqR
  
  						AndCqRR "Three address ops for RISCs; feel free to add and extend"
  
  						CmpRdRd AddRdRd SubRdRd MulRdRd DivRdRd SqrtRd XorRdRd
  						CmpRsRs AddRsRs SubRsRs MulRsRs DivRsRs SqrtRs XorRsRs
  
  						"Conversion"
  						ConvertRRd ConvertRdR
  						ConvertRsRd ConvertRdRs ConvertRsR ConvertRRs
  
  						SignExtend8RR SignExtend16RR SignExtend32RR
  						ZeroExtend8RR ZeroExtend16RR ZeroExtend32RR
  
  						"Advanced bit manipulation (aritmetic)"
  						ClzRR
  						
  						LastRTLCode).
  
  	"Magic auto declaration. Add to the classPool any new variables and nuke any obsolete ones, and assign values"
  	"Find the variables directly referenced by this method"
  	refs := (thisContext method literals select: [:l| l isVariableBinding and: [classPool includesKey: l key]]) collect:
  				[:ea| ea key].
  	"Move to Undeclared any opcodes in classPool not in opcodes or this method."
  	(classPool keys reject: [:k| (opcodeNames includes: k) or: [refs includes: k]]) do:
  		[:k|
  		Undeclared declare: k from: classPool].
  	"Declare as class variables and number elements of opcodeArray above"
  	opcodeNames withIndexDo:
  		[:classVarName :value|
  		self classPool
  			declare: classVarName from: Undeclared;
  			at: classVarName put: value].
  
  	"For CogAbstractInstruction>>isJump etc..."
  	FirstJump := JumpFull.
  	LastJump := JumpFPUnordered.
  	FirstShortJump := Jump.
  
  	"And now initialize the backends; they add their own opcodes and hence these must be reinitialized."
  	(Smalltalk classNamed: #CogAbstractInstruction) ifNotNil:
  		[:cogAbstractInstruction| cogAbstractInstruction allSubclasses do: [:sc| sc initialize]]!



More information about the Vm-dev mailing list