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]"]!
vm-dev@lists.squeakfoundation.org