tim Rowledge uploaded a new version of Cog to project VM Maker: http://source.squeak.org/VMMaker/Cog-tpr.322.mcz
==================== Summary ====================
Name: Cog-tpr.322 Author: tpr Time: 21 May 2016, 10:54:50.890085 am UUID: de0414b6-8d89-4319-9243-f7e4c0db3206 Ancestors: Cog-eem.321
Update ARM simulation of FP code; not complete as yet but mostly there.
=============== Diff against Cog-eem.321 ===============
Item was added: + ----- Method: GdbARMAlien>>fpCPSR (in category 'accessing') ----- + fpCPSR + "The VFP cpsr flags are kept as a single word in the Alien structure. Return just the top 4 bits, the actual flags" + ^(self unsignedLongAt: 1785) >>28!
Item was added: + ----- Method: GdbARMAlien>>handleBasicDoubleArithmetic:at: (in category 'floating-point emulation') ----- + handleBasicDoubleArithmetic: instr at: pc + "Emulate a basic math - add/sub/mul/div - VFP instruction." + | rn rd rm vn vm | + rn := instr >> 16 bitAnd: 15. + rd := instr >> 12 bitAnd: 15. + rm := instr bitAnd: 15. + vn := Float fromIEEE64BitWord: (self perform: (self registerStateGetters at: rn + 18)). "Assume accesses fp regs" + vm := Float fromIEEE64BitWord: (self perform: (self registerStateGetters at: rm + 18)). "Assume accesses fp regs" + + "simplest to match the entire instruction pattern rather than mess around shifting and masking and merging" + (instr bitAnd: 16rFF00FF0) + caseOf: { + [16rE200B00 "FMULD"] -> + [| r | + r := vn * vm. + self perform: (self registerStateSetters at: rd + 18) with: r asIEEE64BitWord]. + [16rE300B00 "FADDD"] -> + [| r | + r := vn + vm. + self perform: (self registerStateSetters at: rd + 18) with: r asIEEE64BitWord]. + [16rE300B40 "FSUBD"] -> + [| r | + r := vn - vm. + self perform: (self registerStateSetters at: rd + 18) with: r asIEEE64BitWord]. + [16rE800B00"FDIVD"] -> + [| r | + r := vn / vm. + self perform: (self registerStateSetters at: rd + 18) with: r asIEEE64BitWord].} + otherwise: [self reportPrimitiveFailure]. + self pc: pc + 4!
Item was added: + ----- Method: GdbARMAlien>>handleExtendedDoubleArithmetic:at: (in category 'floating-point emulation') ----- + handleExtendedDoubleArithmetic: instr at: pc + "Emulate an extended math - cmp/sqrt/sitod - VFP instruction." + | rn rd rm vn vm vd | + rn := instr >> 16 bitAnd: 15. + rd := instr >> 12 bitAnd: 15. + rm := instr bitAnd: 15. + vn := Float fromIEEE64BitWord: (self perform: (self registerStateGetters at: rn + 18)). "Assume accesses fp regs" + vm := Float fromIEEE64BitWord: (self perform: (self registerStateGetters at: rm + 18)). "Assume accesses fp regs" + + "simplest to match the entire instruction pattern rather than mess around shifting and masking and merging" + (instr bitAnd: 16rFF00FF0) + caseOf: { + [16rEB80B80 "FCMPD"] -> + ["read rd, compare with rm (ignore rn) and set FPSCR NZCV flags. Sigh" + vd := Float fromIEEE64BitWord: (self perform: (self registerStateGetters at: rd + 18)). + self break]. + [16rEB80BC0 "FSITOD"] -> + [| r | + r := vm asFloat. + self perform: (self registerStateSetters at: rd + 18) with: r asIEEE64BitWord]. + [16rEB10BC0 "FSQRTD"] -> + [| r | + r := vm sqrt. + self perform: (self registerStateSetters at: rd + 18) with: r asIEEE64BitWord]. + } + otherwise: [self reportPrimitiveFailure]. + self pc: pc + 4!
Item was added: + ----- Method: GdbARMAlien>>handleFPLoadStore:at: (in category 'floating-point emulation') ----- + handleFPLoadStore: instr at: pc + "Emulate a VFP load/store instruction." + | rn rd offset | + rn := instr >> 16 bitAnd: 15. + rd := instr >> 12 bitAnd: 15. + offset := instr bitAnd: 16rFF. + + "examine the U and Lbits" + (instr >>20 bitAnd: 16rF) + caseOf: { + [0"Store neg"] -> + [| r addr| + addr := (self register: rn) - (offset<<2). + r := self perform: (self registerStateGetters at: rd + 18). + self unsignedLongLongAt: addr put: r]. + [1"Load neg"] -> + [| r addr| + addr := (self register: rn) - (offset<<2). + r := self unsignedLongLongAt: addr. + self perform: (self registerStateSetters at: rd + 18) with: r ]. + [8"Store pos"] -> + [| r addr| + addr := (self register: rn) + (offset<<2). + r := self perform: (self registerStateGetters at: rd + 18). + self unsignedLongLongAt: addr put: r]. + [9"Load pos"] -> + [| r addr| + addr := (self register: rn) + (offset<<2). + r := self unsignedLongLongAt: addr. + self perform: (self registerStateSetters at: rd + 18) with: r ].} + otherwise: [self reportPrimitiveFailure]. + self pc: pc + 4!
Item was added: + ----- Method: GdbARMAlien>>handleFPStatus:at: (in category 'floating-point emulation') ----- + handleFPStatus: instr at: pc + "Emulate transferring the FP status to the ARM CPSR." + | fpcpsr | + fpcpsr := self fpCPSR. + self vflag: (fpcpsr bitAnd: 1). + self cflag: ((fpcpsr >>1) bitAnd: 1). + self zflag: ((fpcpsr >>2) bitAnd: 1). + self nflag: ((fpcpsr >>3) bitAnd: 1). + self pc: pc + 4!
Item was changed: ----- Method: GdbARMAlien>>handleFailingFPArithmetic:at: (in category 'error handling') ----- handleFailingFPArithmetic: instr at: pc + + "basic arithmetic" + (instr bitAnd: 16rF400FB0) = 16rE000B00 ifTrue: + [^self handleBasicDoubleArithmetic: instr at: pc]. + + "extension instructions sqrt/cmp/sitod" + (instr bitAnd: 16rFF00F70) = 16rEB00B40 ifTrue: + [^self handleExtendedDoubleArithmetic: instr at: pc]. + + "move ARM reg to coproc reg. " + (instr bitAnd: 16rFF00FFF) = 16rE000A10 ifTrue: + [^self handleRegToDoubleTransfer: instr at: pc]. + + "move FPSCR reg to ARM CPSR" + (instr bitAnd: 16rFFFFFFF) = 16rEF1FA10 ifTrue: + [^self handleFPStatus: instr at: pc]. + + "load and store ops. All doubles; we only use FLDD & FSTD" + (instr bitAnd: 16rF600F00) = 16rD000B00 ifTrue: + [^self handleFPLoadStore: instr at: pc]. + + - | oneRegTransferMask twoRegTransferMask | - oneRegTransferMask := 16rF000F00. - (instr bitAnd: oneRegTransferMask) = 16rE000B00 ifTrue: - [^self handleOneRegTransferDoubleArithmetic: instr at: pc]. - (instr bitAnd: oneRegTransferMask) = 16rE000A00 ifTrue: - [^self handleOneRegTransferSingleArithmetic: instr at: pc]. - twoRegTransferMask := 16rFE00FC0. - (instr bitAnd: twoRegTransferMask) = 16rC400B00 ifTrue: - [^self handleTwoRegTransferDoubleArithmetic: instr at: pc]. - (instr bitAnd: twoRegTransferMask) = 16rC400A00 ifTrue: - [^self handleTwoRegTransferSingleArithmetic: instr at: pc]. ^self reportPrimitiveFailure!
Item was added: + ----- Method: GdbARMAlien>>handleRegToDoubleTransfer:at: (in category 'floating-point emulation') ----- + handleRegToDoubleTransfer: instr at: pc + "Emulate an ARM to VFP instruction." + | rn rd vn | + rn := (instr >> 16 bitAnd: 15) << 1 bitOr: (instr >>6 bitAnd: 1). + rd := instr >> 12 bitAnd: 15. + vn := self register: rn. + + self perform: (self registerStateSetters at: rd + 18) with: vn. + self pc: pc + 4!
Item was changed: ----- Method: GdbARMAlien>>instructionIsAnyFPArithmetic: (in category 'testing') ----- instructionIsAnyFPArithmetic: instr + "Identify VFP instructions. + See C3.1 - C3.4 in the ARM ARM v5 DDI01001." + | cp isFP | + + "All FP instructions are coprocessor instructions on coproc 10 or 11" + cp := instr>>8 bitAnd: 16rF. + isFP := cp = 10 or:[cp = 11]. + (isFP and: [(instr>>25 bitAnd: 7) = 6]) ifTrue: [^true]. + (isFP and: [(instr>>24 bitAnd: 16rF) = 16rE]) ifTrue: [^true]. + + "nope" - "Identify single register transfer and double register transfer VFP instructions. - See C3.3 & C3.4 in the ARM ARM." - | oneRegTransferMask twoRegTransferMask | - oneRegTransferMask := 16rF000F00. - (instr bitAnd: oneRegTransferMask) = 16rE000A00 ifTrue: - [^true]. - (instr bitAnd: oneRegTransferMask) = 16rE000B00 ifTrue: - [^true]. - twoRegTransferMask := 16rFE00FC0. - (instr bitAnd: twoRegTransferMask) = 16rC400A00 ifTrue: - [^true]. - (instr bitAnd: twoRegTransferMask) = 16rC400B00 ifTrue: - [^true]. ^false!
vm-dev@lists.squeakfoundation.org