[Vm-dev] VM Maker: Cog-rmacnak.296.mcz

commits at source.squeak.org commits at source.squeak.org
Wed Nov 18 06:02:29 UTC 2015


Ryan Macnak uploaded a new version of Cog to project VM Maker:
http://source.squeak.org/VMMaker/Cog-rmacnak.296.mcz

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

Name: Cog-rmacnak.296
Author: rmacnak
Time: 17 November 2015, 10:02:15.909 pm
UUID: 464e0274-72d2-4658-aac6-a375581d43cc
Ancestors: Cog-rmacnak.295

Get MIPSEL up to the first CPIC extension.

Add PREF instruction.
Implement transitions out of simulation on page faults.

=============== Diff against Cog-rmacnak.295 ===============

Item was changed:
  SharedPool subclass: #MIPSConstants
  	instanceVariableNames: ''
+ 	classVariableNames: 'A0 A1 A2 A3 ADDIU ADDU AND ANDI AT BEQ BGEZ BGTZ BLEZ BLTZ BNE BREAK FP GP HintLoad HintStore J JAL JALR JR K0 K1 LB LBU LH LHU LUI LW OR ORI OneInstruction PREF R0 R1 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R2 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 R3 R30 R31 R4 R5 R6 R7 R8 R9 RA REGIMM S0 S1 S2 S3 S4 S5 S6 S7 SB SH SLL SLLV SLT SLTI SLTIU SLTU SP SPECIAL SRA SRAV SRL SRLV SUBU SW T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 TwoInstructions V0 V1 XOR XORI ZR'
- 	classVariableNames: 'A0 A1 A2 A3 ADDIU ADDU AND ANDI AT BEQ BGEZ BGTZ BLEZ BLTZ BNE BREAK FP GP J JAL JALR JR K0 K1 LB LBU LH LHU LUI LW OR ORI OneInstruction R0 R1 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R2 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 R3 R30 R31 R4 R5 R6 R7 R8 R9 RA REGIMM S0 S1 S2 S3 S4 S5 S6 S7 SB SH SLL SLLV SLT SLTI SLTIU SLTU SP SPECIAL SRA SRAV SRL SRLV SUBU SW T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 TwoInstructions V0 V1 XOR XORI ZR'
  	poolDictionaries: ''
  	category: 'Cog-Processors'!
  
  !MIPSConstants commentStamp: 'rmacnak 11/11/2015 20:29:59' prior: 0!
  MIPS opcodes and register names.!

Item was changed:
  ----- Method: MIPSConstants class>>initialize (in category 'as yet unclassified') -----
  initialize
  	super initialize.
  	
  	OneInstruction := 4.
  	TwoInstructions := 8.
  	
+ 	HintLoad := 0.
+ 	HintStore := 1.
+ 		
  	self initializeRegisters.
  	self initializeOpcodes.
  	self initializeSpecialFunctions.
  	self initializeRegImmRts.!

Item was changed:
  ----- Method: MIPSConstants class>>initializeOpcodes (in category 'as yet unclassified') -----
  initializeOpcodes
  	SPECIAL := 0.
  	REGIMM := 1.
  	J := 2.
  	JAL := 3.
  	BEQ := 4.
  	BNE := 5.
  	BLEZ := 6.
  	BGTZ := 7.
  	ADDIU := 9.
  	SLTI := 10.
  	SLTIU := 11.
  	ANDI := 12.
  	ORI := 13.
  	XORI := 14.
  	LUI := 15.
  	LB := 32.
  	LH := 33.
  	LW := 35.
  	LBU := 36.
  	LHU := 37.
  	SB := 40.
  	SH := 41.
+ 	SW := 43.
+ 	PREF := 51.!
- 	SW := 43.!

Item was changed:
  ----- Method: MIPSDisassembler>>disassemble:from:to:for:labels:on: (in category 'as yet unclassified') -----
  disassemble: memory from: startPC to: limitPC for: aSymbolManager "<Cogit>" labels: labelDictionary on: aStream
- 	aStream print: labelDictionary;cr.
  	pc := startPC.
  	[pc < limitPC] whileTrue:
  		[ | word instruction |
  		pc printOn: aStream base: 16 nDigits: 8.
  		aStream space; space.
  		word := memory unsignedLongAt: pc + 1.
  		word printOn: aStream base: 16 nDigits: 8.
  		aStream space; space.
  		instruction := MIPSInstruction new value: word.
  		aStream nextPutAll: (instruction decodeFor: self).
+ 
+ 		aSymbolManager ifNotNil: [
+ 			(aSymbolManager labelForPC: pc) ifNotNil:
+ 				[:label | aStream nextPutAll: ' ;'; nextPutAll: label]].
+ 		"aStream print: (aSymbolManager lookupAddress: pc)."
+ 
  		aStream cr.
  		pc := pc + OneInstruction].!

Item was added:
+ ----- Method: MIPSDisassembler>>prefetch: (in category 'instructions - memory') -----
+ prefetch: instruction
+ 	| hintName |
+ 	instruction rt = HintLoad ifTrue: [hintName :=  'load'].
+ 	instruction rt = HintStore ifTrue: [hintName :=  'store'].
+ 	^'pref ', hintName, ', ',
+ 	(instruction signedImmediate printString), '(',
+ 	(MIPSConstants nameForRegister: instruction rs), ')'!

Item was added:
+ ----- Method: MIPSELSimulator>>executeFault: (in category 'memory') -----
+ executeFault: address
+ 	| jumpInstruction type |
+ 	self assert: inDelaySlot not.
+ 	jumpInstruction := MIPSInstruction new value: (self fetchInstruction: jumpingPC).
+ 	jumpInstruction opcode = J ifTrue: [type := #jump].
+ 	jumpInstruction opcode = JAL ifTrue: [type := #call].
+ 	jumpInstruction opcode = SPECIAL ifTrue: 
+ 		[jumpInstruction function = JR ifTrue:
+ 			[jumpInstruction rs = RA
+ 				ifTrue: [type := #return]
+ 				ifFalse: [type := #jump]].
+ 		jumpInstruction function = JALR ifTrue:
+ 			[type := #call]].
+ 	self assert: type ~~ nil.
+ 
+ 	^(ProcessorSimulationTrap
+ 			pc: nil
+ 			nextpc: nil
+ 			address: address
+ 			type: type
+ 			accessor: nil)
+ 		signal!

Item was changed:
+ ----- Method: MIPSELSimulator>>fetchInstruction: (in category 'memory') -----
- ----- Method: MIPSELSimulator>>fetchInstruction: (in category 'as yet unclassified') -----
  fetchInstruction: address
  	address < exectuableBase ifTrue: [self executeFault: address].
  	address > exectuableLimit ifTrue: [self executeFault: address].
  	(address bitAnd: 3) = 0 ifFalse: [self error: 'Unaligned read'].
  	^memory unsignedLongAt: address + 1 bigEndian: false!

Item was changed:
+ ----- Method: MIPSELSimulator>>readFault: (in category 'memory') -----
- ----- Method: MIPSELSimulator>>readFault: (in category 'as yet unclassified') -----
  readFault: address
+ 	| destReg |
+ 	self assert: inDelaySlot not. "Or we have to store nextPC somewhere."
+ 	destReg := (MIPSInstruction new value: (self fetchInstruction: pc)) rt.
+ 	
  	^(ProcessorSimulationTrap
  			pc: pc
  			nextpc: pc + 4
  			address: address
  			type: #read
+ 			accessor: (self setterForRegister: destReg))
- 			accessor: nil)
  		signal
  !

Item was changed:
+ ----- Method: MIPSELSimulator>>signedByte: (in category 'memory') -----
- ----- Method: MIPSELSimulator>>signedByte: (in category 'as yet unclassified') -----
  signedByte: address
  	address < readableBase ifTrue: [self readFault: address].
  	address > readableLimit ifTrue: [self readFault: address].
  	^memory signedByteAt: address + 1!

Item was changed:
+ ----- Method: MIPSELSimulator>>signedHalfword: (in category 'memory') -----
- ----- Method: MIPSELSimulator>>signedHalfword: (in category 'as yet unclassified') -----
  signedHalfword: address
  	(address bitAnd: 1) = 0 ifFalse: [self error: 'Unaligned read'].
  	address < readableBase ifTrue: [self readFault: address].
  	address > readableLimit ifTrue: [self readFault: address].
  	^memory signedShortAt: address + 1!

Item was changed:
+ ----- Method: MIPSELSimulator>>signedWord: (in category 'memory') -----
- ----- Method: MIPSELSimulator>>signedWord: (in category 'as yet unclassified') -----
  signedWord: address
  	(address bitAnd: 3) = 0 ifFalse: [self error: 'Unaligned read'].
  	address < readableBase ifTrue: [self readFault: address].
  	address > readableLimit ifTrue: [self readFault: address].		
  	^memory longAt: address + 1!

Item was changed:
  ----- Method: MIPSELSimulator>>signedWord:put: (in category 'memory') -----
  signedWord: address put: value
  	(address bitAnd: 3) = 0 ifFalse: [self error: 'Unaligned read'].
  	address < writableBase ifTrue: [self writeFault: address].
  	address > writableLimit ifTrue: [self writeFault: address].
+ 	^memory longAt: address + 1 put: value!
- 	^memory signedLongAt: address + 1 put: value!

Item was changed:
+ ----- Method: MIPSELSimulator>>unsignedByte: (in category 'memory') -----
- ----- Method: MIPSELSimulator>>unsignedByte: (in category 'as yet unclassified') -----
  unsignedByte: address
  	address < readableBase ifTrue: [self readFault: address].
  	address > readableLimit ifTrue: [self readFault: address].
  	^memory at: address + 1!

Item was changed:
+ ----- Method: MIPSELSimulator>>unsignedHalfword: (in category 'memory') -----
- ----- Method: MIPSELSimulator>>unsignedHalfword: (in category 'as yet unclassified') -----
  unsignedHalfword: address
  	address < readableBase ifTrue: [self readFault: address].
  	address > readableLimit ifTrue: [self readFault: address].
  	(address bitAnd: 1) = 0 ifFalse: [self error: 'Unaligned read'].
  	^memory unsignedShortAt: address + 1 bigEndian: false!

Item was changed:
+ ----- Method: MIPSELSimulator>>unsignedWord: (in category 'memory') -----
- ----- Method: MIPSELSimulator>>unsignedWord: (in category 'as yet unclassified') -----
  unsignedWord: address
  	address < readableBase ifTrue: [self readFault: address].
  	address > readableLimit ifTrue: [self readFault: address].
  	(address bitAnd: 3) = 0 ifFalse: [self error: 'Unaligned read'].
  	^memory unsignedLongAt: address + 1 bigEndian: false!

Item was added:
+ ----- Method: MIPSELSimulator>>writeFault: (in category 'memory') -----
+ writeFault: address
+ 	| srcReg |
+ 	self assert: inDelaySlot not. "Or we have to store nextPC somewhere."
+ 	srcReg := (MIPSInstruction new value: (self fetchInstruction: pc)) rt.
+ 	
+ 	^(ProcessorSimulationTrap
+ 			pc: pc
+ 			nextpc: pc + 4
+ 			address: address
+ 			type: #write
+ 			accessor: (self getterForRegister: srcReg))
+ 		signal
+ !

Item was added:
+ ----- Method: MIPSELSimulatorTests>>testPref (in category 'tests - memory') -----
+ testPref
+ 	self 
+ 		testGenerateInto: 
+ 			[:stream :compiler | 
+ 			stream nextPut: (compiler prefR: A0 offset: 0 hint: HintLoad).
+ 			stream nextPut: (compiler jR: RA).
+ 			stream nextPut: (compiler nop). "Delay slot"]
+ 		disassembly:
+ '00000000  CC800000  pref load, 0(a0)
+ 00000004  03E00008  jr ra
+ 00000008  00000000  nop
+ '		run: 
+ 			[:simulator | 
+ 			"No exception even though the address is not part of memory."
+ 			simulator call: 0 with: -42 with: 0 with: 0 with: 0].!

Item was changed:
  ----- Method: MIPSInstruction>>decodeFor: (in category 'as yet unclassified') -----
  decodeFor: visitor
  	| opcode |
  	opcode := self opcode.
  	opcode = SPECIAL ifTrue: [^self decodeSpecialFor: visitor].
  	opcode = REGIMM ifTrue: [^self decodeRegImmFor: visitor].
  
  	opcode = J ifTrue: [^visitor jump: self].
  	opcode = JAL ifTrue: [^visitor jumpAndLink: self].
  	opcode = BEQ ifTrue: [^visitor branchEqual: self].
  	opcode = BNE ifTrue: [^visitor branchNotEqual: self].
  	opcode = BLEZ ifTrue: [^visitor branchLessEqualZero: self].
  	opcode = BGTZ ifTrue: [^visitor branchGreaterThanZero: self].
  	opcode = ADDIU ifTrue: [^visitor addImmediateUnsigned: self].
  	opcode = SLTI ifTrue: [^visitor setOnLessThanImmediate: self].
  	opcode = SLTIU ifTrue: [^visitor setOnLessThanImmediateUnsigned: self].
  	opcode = ANDI ifTrue: [^visitor andImmediate: self].
  	opcode = ORI ifTrue: [^visitor orImmediate: self].
  	opcode = XORI ifTrue: [^visitor xorImmediate: self].
  	opcode = LUI ifTrue: [^visitor loadUpperImmediate: self].
  	opcode = LB ifTrue: [^visitor loadByte: self].
  	opcode = LH ifTrue: [^visitor loadHalfword: self].
  	opcode = LW ifTrue: [^visitor loadWord: self].
  	opcode = LBU ifTrue: [^visitor loadByteUnsigned: self].
  	opcode = LHU ifTrue: [^visitor loadHalfwordUnsigned: self].
  	opcode = SB ifTrue: [^visitor storeByte: self].
  	opcode = SH ifTrue: [^visitor storeHalfword: self].
  	opcode = SW ifTrue: [^visitor storeWord: self].
+ 	opcode = PREF ifTrue: [^visitor prefetch: self].
+ 
- 	
  	self error: 'Unknown instruction'.!

Item was changed:
  Object subclass: #MIPSSimulator
+ 	instanceVariableNames: 'memory registers pc instructionCount inDelaySlot readableBase writableBase exectuableBase readableLimit writableLimit exectuableLimit jumpingPC'
- 	instanceVariableNames: 'memory registers pc instructionCount inDelaySlot readableBase writableBase exectuableBase readableLimit writableLimit exectuableLimit'
  	classVariableNames: 'EndSimulationPC'
  	poolDictionaries: 'MIPSConstants'
  	category: 'Cog-Processors'!
  
  !MIPSSimulator commentStamp: 'rmacnak 11/11/2015 20:33:00' prior: 0!
  Simulator for 32-bit MIPS, without implementation of memory access.!

Item was added:
+ ----- Method: MIPSSimulator>>cResultRegister: (in category 'processor api') -----
+ cResultRegister: cResult
+ 	^self unsignedRegister: V0 put: cResult!

Item was changed:
  ----- Method: MIPSSimulator>>call:with:with:with:with: (in category 'as yet unclassified') -----
  call: entryPC with: arg0 with: arg1 with: arg2 with: arg3.
  	
  	pc := entryPC.
  	self unsignedRegister: RA put: EndSimulationPC.
  	self signedRegister: A0 put: arg0.
  	self signedRegister: A1 put: arg1.
  	self signedRegister: A2 put: arg2.
  	self signedRegister: A3 put: arg3.
  	
  	self execute.
  	
  	^self signedRegister: V0.!

Item was changed:
  ----- Method: MIPSSimulator>>execute (in category 'as yet unclassified') -----
  execute
  	| instruction |
  	[pc ~= EndSimulationPC] whileTrue: 
+ 		[Transcript nextPutAll: 'X '; nextPutAll: self currentInstruction; flush.
+ 		 10 milliSeconds asDelay wait.
- 		[Transcript nextPutAll: '* '; nextPutAll: self currentInstruction; flush.
  		 instruction := MIPSInstruction new value: (self fetchInstruction: pc).
  		 instruction decodeFor: self.
  		 pc := pc + OneInstruction].!

Item was changed:
  ----- Method: MIPSSimulator>>executeDelaySlot (in category 'as yet unclassified') -----
  executeDelaySlot
  	| instruction |
  	self assert: inDelaySlot not.
  	inDelaySlot := true.
+ 	Transcript nextPutAll: 'D '; nextPutAll: self currentInstruction; flush.
  	instruction := MIPSInstruction new value: (self fetchInstruction: pc).
  	instruction decodeFor: self.
  	inDelaySlot := false.!

Item was changed:
+ ----- Method: MIPSSimulator>>fp (in category 'registers') -----
- ----- Method: MIPSSimulator>>fp (in category 'processor api') -----
  fp
  	^self signedRegister: FP!

Item was added:
+ ----- Method: MIPSSimulator>>fp: (in category 'registers') -----
+ fp: anInteger
+ 	^self signedRegister: FP put: anInteger!

Item was added:
+ ----- Method: MIPSSimulator>>getterForRegister: (in category 'as yet unclassified') -----
+ getterForRegister: registerNumber
+ 	^#(zr at v0 v1 a0 a1 a2 a3
+ 		t0 t1 t2 t3 t4 t5 t6 t7
+ 		s0 s1 s2 s3 s4 s5 s6 s7
+ 		t8 t9 k0 k1 gp sp fp ra) at: registerNumber + 1!

Item was changed:
  ----- Method: MIPSSimulator>>initializeWithMemory: (in category 'as yet unclassified') -----
  initializeWithMemory: aByteArray
+ 	memory := aByteArray.
+ 	readableBase := 0.
+ 	writableBase := 0.
+ 	exectuableBase := 0.
+ 	readableLimit := memory size.
+ 	writableLimit := memory size.
+ 	exectuableLimit := memory size.!
- 	memory := aByteArray.!

Item was changed:
  ----- Method: MIPSSimulator>>jump: (in category 'instructions - control') -----
  jump: instruction
  	| nextPC |
  	self assert: inDelaySlot not.
+ 	jumpingPC := pc.
  	pc := pc + OneInstruction.
  	nextPC := (pc bitAnd: 16rF0000000) + (instruction target << 2). "Region is that of the delay slot."	
  	self executeDelaySlot.
  	pc := nextPC - OneInstruction. "Account for general increment"!

Item was changed:
  ----- Method: MIPSSimulator>>jumpAndLink: (in category 'instructions - control') -----
  jumpAndLink: instruction
  	| nextPC |
  	self assert: inDelaySlot not.
  	self unsignedRegister: RA put: pc + TwoInstructions. "Return past delay slot."
+ 	jumpingPC := pc.
  	pc := pc + OneInstruction.
  	nextPC := (pc bitAnd: 16rF0000000) + (instruction target << 2). "Region is that of the delay slot."	
  	self executeDelaySlot.
  	pc := nextPC - OneInstruction. "Account for general increment"!

Item was changed:
  ----- Method: MIPSSimulator>>jumpAndLinkRegister: (in category 'instructions - control') -----
  jumpAndLinkRegister: instruction
  	| nextPC |
  	self assert: inDelaySlot not.
  	self unsignedRegister: instruction rd put: pc + TwoInstructions. "Return past delay slot."
  	nextPC := self unsignedRegister: instruction rs.
+ 	jumpingPC := pc.
  	pc := pc + OneInstruction.
  	self executeDelaySlot.
  	pc := nextPC.
  	pc := pc - 4. "Account for general increment"!

Item was changed:
  ----- Method: MIPSSimulator>>jumpRegister: (in category 'instructions - control') -----
  jumpRegister: instruction
  	| nextPC |
  	self assert: inDelaySlot not.
  	nextPC := self unsignedRegister: instruction rs.
+ 	jumpingPC := pc.
  	pc := pc + OneInstruction.
  	self executeDelaySlot.
  	pc := nextPC.
  	pc := pc - 4. "Account for general increment"!

Item was added:
+ ----- Method: MIPSSimulator>>postCallArgumentsNumArgs:in: (in category 'processor api') -----
+ postCallArgumentsNumArgs: numArgs "<Integer>" in: memory "<ByteArray|Bitmap>"
+ 	"Answer an argument vector of the requested size after a vanilla ABI call. 
+ 	 We assume that all arguments are single word arguments, which can not be
+ 	 supplied on co-processor-registers. For compatibility with Cog/Slang we answer
+ 	 unsigned values."
+ 	self flag: #OABI.
+ 	
+ 	numArgs = 0 ifTrue: 
+ 		[^{}].
+ 	numArgs = 1 ifTrue: 
+ 		[^{self unsignedRegister: A0}].
+ 	numArgs = 2 ifTrue:
+ 		[^{self unsignedRegister: A0. self unsignedRegister: A1}].
+ 	numArgs = 3 ifTrue:
+ 		[^{self unsignedRegister: A0. self unsignedRegister: A1. self unsignedRegister: A2}].
+ 	numArgs = 4 ifTrue:
+ 		[^{self unsignedRegister: A0. self unsignedRegister: A1. self unsignedRegister: A2. self unsignedRegister: A3}].
+ 	self unimplemented.!

Item was added:
+ ----- Method: MIPSSimulator>>prefetch: (in category 'instructions - memory') -----
+ prefetch: instruction
+ 	self assert: (instruction rt = HintLoad or: [instruction rt = HintStore]).!

Item was added:
+ ----- Method: MIPSSimulator>>pushWord:in: (in category 'processor api') -----
+ pushWord: aValue in: aMemory
+ 	aMemory longAt: (self sp: self sp - 4) + 1 put: aValue bigEndian: false!

Item was added:
+ ----- Method: MIPSSimulator>>ra (in category 'registers') -----
+ ra
+ 	^self signedRegister: RA!

Item was added:
+ ----- Method: MIPSSimulator>>setterForRegister: (in category 'as yet unclassified') -----
+ setterForRegister: registerNumber
+ 	^#(zr: at: v0: v1: a0: a1: a2: a3:
+ 		t0: t1: t2: t3: t4: t5: t6: t7:
+ 		s0: s1: s2: s3: s4: s5: s6: s7:
+ 		t8: t9: k0: k1: gp: sp: fp: ra:) at: registerNumber + 1!

Item was changed:
  ----- Method: MIPSSimulator>>signedRegister:put: (in category 'registers') -----
  signedRegister: registerNumber put: signedValue
  	self assert: (signedValue between: -16r80000000 and: 16r7FFFFFFF).
+ 	registerNumber == ZR ifFalse: [^registers at: registerNumber + 1 put: signedValue].!
- 	registerNumber == ZR ifFalse: [registers at: registerNumber + 1 put: signedValue].!

Item was added:
+ ----- Method: MIPSSimulator>>simulateCallOf:nextpc:memory: (in category 'processor api') -----
+ simulateCallOf: address nextpc: nextpc memory: aMemory
+ 	"Simulate a frame-building call of address.  Build a frame since
+ 	a) this is used for calls into the run-time which are unlikely to be leaf-calls"
+ 	
+ 	self flag: #todo. "Why are we building a frame exactly? Frame building is a callee's job, which I'd expect to be done by some code under simulation. --rmacnak"
+ 	
+ 	self pushWord: self ra in: aMemory.
+ 	self pushWord: self fp in: aMemory.
+ 	self fp: self sp.
+ 	pc := address.!

Item was changed:
+ ----- Method: MIPSSimulator>>sp (in category 'registers') -----
- ----- Method: MIPSSimulator>>sp (in category 'processor api') -----
  sp
  	^self signedRegister: SP!

Item was added:
+ ----- Method: MIPSSimulator>>sp: (in category 'registers') -----
+ sp: anInteger
+ 	^self signedRegister: SP put: anInteger!

Item was changed:
  ----- Method: MIPSSimulator>>unsignedRegister:put: (in category 'registers') -----
  unsignedRegister: registerNumber put: unsignedValue
  	registerNumber == ZR ifFalse:
+ 		[^registers at: registerNumber + 1 put: (self unsigned32ToSigned32: unsignedValue)].!
- 		[registers at: registerNumber + 1 put: (self unsigned32ToSigned32: unsignedValue)].!



More information about the Vm-dev mailing list