[Vm-dev] VM Maker: Cog-tpr.256.mcz

commits at source.squeak.org commits at source.squeak.org
Thu Apr 2 02:15:07 UTC 2015


tim Rowledge uploaded a new version of Cog to project VM Maker:
http://source.squeak.org/VMMaker/Cog-tpr.256.mcz

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

Name: Cog-tpr.256
Author: tpr
Time: 1 April 2015, 7:14:56.966 pm
UUID: 9426834f-7cf6-406a-9048-6159ddc0e37f
Ancestors: Cog-eem.255

Improve instruction decorating for BX/BLX.
MC seems to insist on including some stuff changed and saved in an older version; hunh?

=============== Diff against Cog-eem.255 ===============

Item was changed:
  ----- Method: GdbARMAlien>>decorateDisassembly:for:fromAddress: (in category 'disassembly') -----
  decorateDisassembly: anInstructionString for: aSymbolManager fromAddress: address
+ "Decode what we can of the instruction and decorate it with useful stuff"
  	| word opcode rotate mode operand |
  	word := aSymbolManager objectMemory longAt: address.
  	(self instructionIsAnyB: word)
  		ifTrue:
+ 			[((self instructionIsB: word) or: [self instructionIsBL: word])
+ 				ifTrue:["We can extract the offset from a plain B/BL instruction"
+ 					operand := self extractOffsetFromBL: word..
+ 					 operand := operand + address + 8 bitAnd: aSymbolManager addressSpaceMask].
+ 			((self instructionIsBX: word) or: [self instructionIsBLX: word])
+ 				ifTrue:["We can extract the offset from a  BX/BLX instructions register"			
+ 					operand := (self perform: (self registerStateGetters at: (word bitAnd: 15) + 1))]]
- 			[operand := word bitAnd: 16rFFFFFF.
- 			 (operand anyMask: 16r800000) ifTrue:
- 				[operand := operand - 16r1000000].
- 			 operand := operand * 4 + address + 8 bitAnd: aSymbolManager addressSpaceMask]
  		ifFalse:
  			[((self instructionIsAnyLoadStore: word)
  			  and: [(word >> 16 bitAnd: 15) = CogARMCompiler VarBaseReg])
  				ifTrue:
  					[operand := aSymbolManager varBaseAddress + (word bitAnd: 1 << 12 - 1)]
  				ifFalse:
  					[opcode := word >> 21 bitAnd: 16rF.
  					 opcode ~= CogARMCompiler orOpcode ifTrue:
  						[^anInstructionString].
  					 rotate := word >> 8 bitAnd: 16rF.
  					 mode := word >> 25 bitAnd: 7.
  					 "CogARMCompiler always uses a 0 rotate in the last operand of the final ORR when building long constants."
  					 (mode = 1 and: [rotate ~= 0]) ifTrue:
  						[^anInstructionString].
  					 operand := aSymbolManager backEnd literalBeforeFollowingAddress: address + 4]].
  	"is there an intersting address with this?"
  	^(aSymbolManager lookupAddress: operand)
  		ifNotNil: [:string| anInstructionString, ' = ', (operand printStringRadix: 16), ' = ', string]
  		ifNil: [anInstructionString, ' = ', (operand printStringRadix: 16)]!

Item was added:
+ ----- Method: GdbARMAlien>>extractOffsetFromLoadStore: (in category 'accessing-abstract') -----
+ extractOffsetFromLoadStore: instr
+ "work out the address offset implied by instr.
+ We assume it has been determined it is actually a load store before attaching any meaning to the result.
+ If it is post-indexed, then the offset must be 0, no matter what else is encoded.
+ If the instr is immediate-offset, pull the relevent bits out of instr.
+ If it is register-offset, pull the value from the indicated register."
+ 	|offset shiftAmt shiftType |
+ 
+ 	"post-indexed means no offset to the read address"
+ 	(instr bitAnd: 1 << 24) = 0 ifTrue:[^0].
+ 	
+ 	(self instructionIsImmediateOffsetLoadStore: instr)
+ 		ifTrue:["two cases apply - a 12bit immediate for 010 group instructions and an 8bit for 000 group ldrh stuff"
+ 			(instr >> 25 bitAnd: 7) = 2
+ 				ifTrue:[ "immed word or byte op, with 12bit offset"
+ 					offset := instr bitAnd: 16rFFF]
+ 				ifFalse:["halfword 8bit offset"
+ 					offset := (instr bitAnd: 16rF00)>>4 bitOr: (instr bitAnd: 16rF)]].
+ 
+ 	(self instructionIsRegisterOffsetLoadStore: instr)
+ 		ifTrue:["both forms use same offset-reg encoding"
+ 			offset := self perform:(self registerStateGetters at:(instr bitAnd: 16rF) + 1).
+ 			(instr >> 25 bitAnd: 7) = 3
+ 				ifTrue:[ "register offset with assorted modifiers"
+ 					"sort out modifiers"
+ 					shiftType := instr >> 5 bitAnd: 3.
+ 					shiftAmt := instr  >>7 bitAnd: 16r1F.
+ 					shiftType = 0"lsl" ifTrue:[offset := offset << shiftAmt.].
+ 					shiftType = 1"lsr" ifTrue:[offset := offset >> shiftAmt].
+ 					shiftType = 2"asr" ifTrue:[offset := offset  >>> shiftAmt].
+ 					"I refuse to countenance using ROR or RRX here. Just Say No" ]
+ 				"halfword stuff register offset uses no modifiers in the form we suport. See ARM DDI0406A p. A8-156"].
+ 
+ 	"all forms have the bit 23 up/down flag to account for"
+ 	(instr bitAnd: 1<<23) = 0
+ 						ifTrue:["-ve offset" ^offset negated]
+ 						ifFalse:["+ve offset" ^offset]	!

Item was changed:
  ----- Method: GdbARMAlien>>handleFailingLoadStore:at: (in category 'error handling') -----
  handleFailingLoadStore: instr at: pc
+ 	"See e.g. ARM DDI0406A pp. A8-120, 124, 128, 132, 152, 156, etc. etc"
  	| baseReg destReg srcReg offset |
+ 
+ 	"find the register used as the base of the address and the register to load into or store from"
  	baseReg := self registerStateGetters at: (instr >> 16 bitAnd: 15)+ 1.
+ 	srcReg :=  self registerStateGetters at: (instr >> 12 bitAnd: 15)+ 1.
  	destReg := self registerStateSetters at: (instr >> 12 bitAnd: 15) + 1.
+ 
+ 	"work out the relevant offset, whether an immediate or register value"
+ 	offset := self extractOffsetFromLoadStore: instr.
+ 	
- 	srcReg := self registerStateGetters at: (instr >> 12 bitAnd: 15) + 1.
- 	"See e.g. A5.2.2/A5-20 ARM ARM v6"
- 	offset := (instr >> 21 bitAnd: 2r1111001) = 2r0101000
- 				ifTrue:
- 					[(instr >> 23 anyMask: 1) "U bit"
- 						ifTrue: [instr bitAnd: 16rFFF]
- 						ifFalse: [(instr bitAnd: 16rFFF) negated]]
- 				ifFalse:
- 					[0].
  	(self instructionIsLDR: instr) ifTrue:
  		[^(ProcessorSimulationTrap
  				pc: pc
  				nextpc: pc + 4 
  				address: (self perform: baseReg) + offset
  				type: #read
  				accessor: destReg)
  			signal].
+ 	(self instructionIsLDRB: instr) ifTrue:
+ 		[^(ProcessorSimulationTrap
+ 				pc: pc
+ 				nextpc: pc + 4 
+ 				address: (self perform: baseReg) + offset
+ 				type: #read
+ 				accessor: destReg)
+ 			signal].
+ 	(self instructionIsLDRH: instr) ifTrue:
+ 		[^(ProcessorSimulationTrap
+ 				pc: pc
+ 				nextpc: pc + 4 
+ 				address: (self perform: baseReg) + offset
+ 				type: #read
+ 				accessor: destReg)
+ 			signal].
  	(self instructionIsSTR: instr) ifTrue:
  		[^(ProcessorSimulationTrap
  				pc: pc
  				nextpc: pc + 4 
  				address: (self perform: baseReg) + offset
  				type: #write
  				accessor: srcReg)
  			signal].
- 	"Lars handled byte read/write failures.  i don't think we need to"
- 	"(self instructionIsLDRB: instr) ifTrue:
- 		[??].
  	(self instructionIsSTRB: instr) ifTrue:
+ 		[^(ProcessorSimulationTrap
+ 				pc: pc
+ 				nextpc: pc + 4 
+ 				address: (self perform: baseReg) + offset
+ 				type: #write
+ 				accessor: srcReg)
+ 			signal].
+ 	(self instructionIsSTRH: instr) ifTrue:
+ 		[^(ProcessorSimulationTrap
+ 				pc: pc
+ 				nextpc: pc + 4 
+ 				address: (self perform: baseReg) + offset
+ 				type: #write
+ 				accessor: srcReg)
+ 			signal].
+ 
- 		[??]."
  	self error: 'handleFailingLoadStore:at: invoked for non-load/store?'!

Item was changed:
  ----- Method: GdbARMAlien>>instructionIsAddSP: (in category 'testing') -----
  instructionIsAddSP: instr
+ "is this an add sp, sp, #? -  instruction?"
- "is this aadd sp, sp, #? -  instruction?"
  	^instr >> 28 < 16rF "test for allowed condcode - 0xF is extension" and: [(instr bitAnd: (16rFFFFF00)) = (16r28DD000)]!

Item was changed:
  ----- Method: GdbARMAlien>>instructionIsAlignSP: (in category 'testing') -----
  instructionIsAlignSP: instr
+ "is this a subs sp, sp, #4 -  instruction?"
+ 	^instr >> 28 < 16rF "test for allowed condcode - 0xF is extension" and: [(instr bitAnd: (16rFFFFFFF)) = (16r2DDD004)]!
- "is this a bics sp, sp, #7 -  instruction?"
- 	^instr >> 28 < 16rF "test for allowed condcode - 0xF is extension" and: [(instr bitAnd: (16rFFFFFFF)) = (16r3DDD007)]!

Item was changed:
  ----- Method: GdbARMAlien>>instructionIsAnyB: (in category 'testing') -----
+ instructionIsAnyB: instr 
- instructionIsAnyB: instr
  	"is this any of the B BX BL or BLX <offset> instructions?"
+ 	^ (self instructionIsB: instr)
+ 		or: [self instructionIsBL: instr]
+ 		or: [self instructionIsBLX: instr]
+ 		or: [self instructionIsBX: instr]!
- 	^(instr >> 25 bitAnd: 7) = 5!

Item was changed:
  ----- Method: GdbARMAlien>>instructionIsAnyLoadStore: (in category 'testing') -----
  instructionIsAnyLoadStore: instr
+ 	"is this any of the LDR,STR instructions?
+ 	We handle byte, word, and halfword versions but NOT NOT signed extend, double or privileged versions"
+ 	
+ 	^(self instructionIsImmediateOffsetLoadStore: instr) or:[self instructionIsRegisterOffsetLoadStore: instr]!
- 	"is this any of the LDR,STR instructions?"
- 	^(instr >> 24 bitAnd: 15) = 5!

Item was changed:
  ----- Method: GdbARMAlien>>instructionIsB: (in category 'testing') -----
  instructionIsB: instr
  "is this a B <offset> instruction?"
+ 	"first test for non-NV condition code; some important instructions use it"
+ 	instr >> 28 = 16rF ifTrue:[^false].
+ 	"See ARM DDI0406A p. A8-44"
+ 	^ (instr bitAnd: (16rF<<24)) = (16rA<<24)!
- 	^instr >> 28 < 16rF "test for allowed condcode - 0xF is extension" and: [(instr bitAnd: (16rF<<24)) = (16rA<<24)]!

Item was changed:
  ----- Method: GdbARMAlien>>instructionIsBL: (in category 'testing') -----
  instructionIsBL: instr
  "is this a BL <offset> instruction?"
+ 	"first test for non-NV condition code; some important instructions use it"
+ 	instr >> 28 = 16rF ifTrue:[^false].
+ 	"see ARM DDI0406A p. A8-58"
+ 	^(instr bitAnd: (16rF<<24)) = (16rB<<24)!
- 	^instr >> 28 < 16rF "test for allowed condcode - 0xF is extension" and: [(instr bitAnd: (16rF<<24)) = (16rB<<24)]!

Item was changed:
  ----- Method: GdbARMAlien>>instructionIsBLX: (in category 'testing') -----
  instructionIsBLX: instr
+ "is this a BLX <targetReg> instruction? We DO NOT support the BLX immed version"
+ 	"first test for non-NV condition code; some important instructions use it"
+ 	instr >> 28 = 16rF ifTrue:[^false].
+ 	"See ARM DDI0406A p A8-60"
+  	^(instr bitAnd: 16r0FFFFFF0) = 16r12FFF30!
- "is this a BLX <targetReg> instruction?"
- 	^instr >> 28 < 16rF "test for allowed condcode - 0xF is extension" and: [(instr bitAnd: 16r0FFFFFF0) = 16r12FFF30]!

Item was changed:
  ----- Method: GdbARMAlien>>instructionIsBX: (in category 'testing') -----
  instructionIsBX: instr
  "is this a BX <targetReg> instruction?"
+ 	"first test for non-NV condition code; some important instructions use it"
+ 	instr >> 28 = 16rF ifTrue:[^false].
+ 	"See ARM DDI0406A p. A8-62"
+  	^(instr bitAnd: 16r0FFFFFF0) = 16r12FFF10!
- 	^instr >> 28 < 16rF "test for allowed condcode - 0xF is extension" and: [(instr bitAnd: 16r0FFFFFF0) = 16r12FFF10]!

Item was added:
+ ----- Method: GdbARMAlien>>instructionIsImmediateOffsetLoadStore: (in category 'testing') -----
+ instructionIsImmediateOffsetLoadStore: instr
+ 	"is this any of the immediate offset LDR,STR instructions?"
+ 	| op1 |
+ 	"first test for non-NV condition code; some important instructions use it"
+ 	instr >> 28 = 16rF ifTrue:[^false].
+ 	"test for 010 group of load/stores"
+ 	op1 := instr >>25 bitAnd: 7.
+ 	op1 = 2 ifTrue:[^true].
+ 
+ 	"test for the ridiculously muddled 000 group"
+ 	op1 > 0 ifTrue:[^false].
+ 	"bit 21 must not be 1 and bit 22 must be 1"
+ 	(instr bitAnd: 3 <<21) = (2<<21) ifFalse:[^false].
+ 	"bits 4:7need to be 16rB for our purpose"
+ 	^(instr bitAnd: 16rF0) = 16rB0
+ 	
+ 	!

Item was changed:
  ----- Method: GdbARMAlien>>instructionIsLDR: (in category 'testing') -----
  instructionIsLDR: instr
  "is this a LDR instruction?"
  	| foo |
+ 	"first test for non-NV condition code; some important instructions use it"
+ 	instr >> 28 = 16rF ifTrue:[^false].
+ 	"See ARM DDI0406A p. A8-120"
+ 	foo := (instr >> 20 bitAnd: 16rE5).
+ 	^foo = 16r41 "ldr r1, [r2, #+/-imm]"
+ 		or:[foo = 16r61 "ldr r1, [r2, r3]"]!
- 	^instr >> 28 < 16rF "test for allowed condcode - 0xF is extension" 
- 		and: [foo := (instr >> 20 bitAnd: 16rFF).
- 			foo = 16r51 "ldr r1, [r2, #imm]"
- 				or:[foo = 16r59 "ldr r1, [r2, #-imm]"
- 				or:[foo = 16r79 "ldr r1, [r2, r3]"]]]!

Item was changed:
  ----- Method: GdbARMAlien>>instructionIsLDRB: (in category 'testing') -----
  instructionIsLDRB: instr
  "is this a LDRB instruction?"
  	| foo |
+ 	"first test for non-NV condition code; some important instructions use it"
+ 	instr >> 28 = 16rF ifTrue:[^false].
+ 	"See ARM DDI0406A p. A8-128"
+ 	foo := (instr >> 20 bitAnd: 16rE5).
+ 	^foo = 16r45 "ldrb r1, [r2, #+/-imm]"
+ 		or:[foo = 16r65 "ldrb r1, [r2, r3]"]!
- 	^instr >> 28 < 16rF "test for allowed condcode - 0xF is extension" 
- 		and: [foo := (instr >> 20 bitAnd: 16rFF).
- 			foo = 16r55 "ldrb r1, [r2, #imm]"
- 				or:[foo = 16r5D "ldrb r1, [r2, #-imm]"
- 				or:[foo = 16r7D "ldrb r1, [r2, r3]"]]]!

Item was added:
+ ----- Method: GdbARMAlien>>instructionIsLDRH: (in category 'testing') -----
+ instructionIsLDRH: instr
+ "is this a LDRH instruction?"
+ 	| foo |
+ 	"first test for non-NV condition code; some important instructions use it"
+ 	instr >> 28 = 16rF ifTrue:[^false].
+ 	"See ARM DDI0406A p. A8-154"
+ 	(instr bitAnd: 16rF0) = 16rB0 ifFalse:[^false].
+ 	foo := (instr >> 20 bitAnd: 16rE3).
+ 	^foo = 16r3 "ldrh r1, [r2, #+/-imm]"
+ 		or:[foo = 16r1 "ldrh r1, [r2, r3]"]!

Item was added:
+ ----- Method: GdbARMAlien>>instructionIsRegisterOffsetLoadStore: (in category 'testing') -----
+ instructionIsRegisterOffsetLoadStore: instr
+ 	"is this any of the register offset LDR,STR instructions?"
+ 	| op1 |
+ 	"first test for non-NV condition code; some important instructions use it"
+ 	instr >> 28 = 16rF ifTrue:[^false].
+ 	
+ 	op1 := instr >>25 bitAnd: 7.
+ 	"test for the 011 group - check bit 4 as well"
+ 	(op1 = 3 and:[(instr bitAnd: 16r10) = 0]) ifTrue:[^true].
+ 	"test for the ridiculously muddled 000 group"
+ 	op1 > 0 ifTrue:[^false].
+ 	"bit 21 & 22 must not be 1"
+ 	(instr bitAnd: 3 <<21) = 0 ifFalse:[^false].
+ 	"bits 4:7need to be 16rB for our purpose"
+ 	^(instr bitAnd: 16rF0) = 16rB0
+ 	
+ 	!

Item was changed:
  ----- Method: GdbARMAlien>>instructionIsSTR: (in category 'testing') -----
  instructionIsSTR: instr
  "is this a STR instruction?"
  	| foo |
+ 	"first test for non-NV condition code; some important instructions use it"
+ 	instr >> 28 = 16rF ifTrue:[^false].
+ 	"See ARM DDI0406A p. A8-382"
+  	foo := (instr >> 20 bitAnd: 16rE5). 
+ 	^foo = 16r40 "str r1, [r2, #+/-imm]" 
+ 		or:[foo = 16r60] "str r1, [r2, #-imm]"!
- 	^instr >> 28 < 16rF "test for allowed condcode - 0xF is extension" and: [foo := (instr >> 20 bitAnd: 16rFF). foo = 16r58 "str r1, [r2, #imm]" or:[foo = 16r50 "str r1, [r2, #-imm]" or:[foo = 16r78 "str r1, [r2, r3]"]]]!

Item was changed:
  ----- Method: GdbARMAlien>>instructionIsSTRB: (in category 'testing') -----
  instructionIsSTRB: instr
  "is this a STRB instruction?"
  	| foo |
+ 	"first test for non-NV condition code; some important instructions use it"
+ 	instr >> 28 = 16rF ifTrue:[^false].
+ 	"See ARM DDI0406A p. A8-388"
+  	foo := (instr >> 20 bitAnd: 16rE5). 
+ 	^foo = 16r44 "strb r1, [r2, #+/-imm]" 
+ 		or:[foo = 16r64] "strb r1, [r2, #-imm]"!
- 	^instr >> 28 < 16rF "test for allowed condcode - 0xF is extension" and: [foo := (instr >> 20 bitAnd: 16rFF). foo = 16r54 "strb r1, [r2, #imm]" or:[foo = 16r5c "strb r1, [r2, #-imm]" or:[foo = 16r7c "strb r1, [r2, r3]"]]]!

Item was added:
+ ----- Method: GdbARMAlien>>instructionIsSTRH: (in category 'testing') -----
+ instructionIsSTRH: instr
+ "is this a STRH instruction?"
+ 	| foo |
+ 	"first test for non-NV condition code; some important instructions use it"
+ 	instr >> 28 = 16rF ifTrue:[^false].
+ 	"See ARM DDI0406A p. A8-154"
+ 	(instr bitAnd: 16rF0) = 16rB0 ifFalse:[^false].
+ 	foo := (instr >> 20 bitAnd: 16rE3).
+ 	^foo = 16r4 "strh r1, [r2, #+/-imm]"
+ 		or:[foo = 16r0 "strh r1, [r2, r3]"]!



More information about the Vm-dev mailing list