[Vm-dev] VM Maker: VMMaker.oscog-eem.1429.mcz
Nicolas Cellier
nicolas.cellier.aka.nice at gmail.com
Fri Aug 7 20:36:23 UTC 2015
2015-08-07 20:47 GMT+02:00 <commits at source.squeak.org>:
>
> Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
> http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1429.mcz
>
> ==================== Summary ====================
>
> Name: VMMaker.oscog-eem.1429
> Author: eem
> Time: 7 August 2015, 11:46:05.819 am
> UUID: 446c2481-93c9-43bc-86ac-0743223bfa0c
> Ancestors: VMMaker.oscog-rmacnak.1428
>
> Fix Integer receiver, float arg comparison with NaNs in the machine-code
> primitive. This has started failing in the FloatTest>>testNaNCompare since
> the new machine-code perform primitive invoked the machine-code version of
> the primitive. The Interpretewr code has always been correct and the old
> perform primitive would always run the Interpreter primitive if it exsted,
> since this would probably be faster.
>
> Luckily the ARM requires no changes. It can continue to use FCMP instead
> of FCMPE. Include a generator for the FCMPE instruction; it got written to
> experiment and does no harm remaining there unused.
>
> Refactor stack page list printing to include use counts.
>
> Simulator:
> Simplify and clean-up directory entry call.
>
> =============== Diff against VMMaker.oscog-rmacnak.1428 ===============
>
> Item was added:
> + ----- Method: CogARMCompiler>>fcmpeFrom:to: (in category 'ARM
> convenience instructions') -----
> + fcmpeFrom: regA to: regB
> + "FCMPE or VCMPE instruction to compare two fpu double registers.
> + ARM_ARM v5 DDI 01001.pdf pp. C4-12"
> + <inline: true>
> + ^(2r11101110101101000000101111000000 bitOr: (regA <<12)) bitOr:
> regB!
>
> Item was changed:
> ----- Method: CogVMSimulator>>primitiveDirectoryEntry (in category 'file
> primitives') -----
> primitiveDirectoryEntry
> | name pathName array result |
> name := self stringOf: self stackTop.
> pathName := self stringOf: (self stackValue: 1).
>
> self successful ifFalse:
> [^self primitiveFail].
>
> array := FileDirectory default primLookupEntryIn: pathName name:
> name.
> array == nil ifTrue:
> [self pop: 3 thenPush: objectMemory nilObject.
> ^array].
> array == #badDirectoryPath ifTrue:
> [self halt.
> ^self primitiveFail].
>
> PharoVM
> ifTrue: [
> result := self makeDirEntryName: (array at: 1)
> size: (array at: 1) size
> createDate: (array at: 2) modDate: (array
> at: 3)
> isDir: (array at: 4) fileSize: (array at:
> 5)
> posixPermissions: (array at: 6) isSymlink:
> (array at: 7) ]
> ifFalse: [
> result := self makeDirEntryName: (array at: 1)
> size: (array at: 1) size
> createDate: (array at: 2) modDate: (array
> at: 3)
> isDir: (array at: 4) fileSize: (array at:
> 5) ].
> + self pop: 3 thenPush: result!
> - self pop: 3.
> - self push: result!
>
> Item was removed:
> - ----- Method:
> InterpreterSimulator>>makeDirEntryName:size:createDate:modDate:isDir:fileSize:posixPermissions:
> (in category 'file primitives') -----
> - makeDirEntryName: entryName size: entryNameSize createDate: createDate
> modDate: modifiedDate isDir: dirFlag fileSize: posixPermissions
> posixPermissions: fileSize
> - <option: #PharoVM>
> - <var: 'entryName' type: 'char *'>
> -
> - | modDateOop createDateOop nameString results |
> -
> - "allocate storage for results, remapping newly allocated
> - oops in case GC happens during allocation"
> - self pushRemappableOop:
> - (self instantiateClass: (self splObj: ClassArray)
> indexableSize: 5).
> - self pushRemappableOop:
> - (self instantiateClass: (self splObj: ClassString)
> indexableSize: entryNameSize)..
> - self pushRemappableOop: (self positive32BitIntegerFor: createDate).
> - self pushRemappableOop: (self positive32BitIntegerFor:
> modifiedDate).
> -
> - modDateOop := self popRemappableOop.
> - createDateOop := self popRemappableOop.
> - nameString := self popRemappableOop.
> - results := self popRemappableOop.
> -
> - 1 to: entryNameSize do: [ :i |
> - self storeByte: i-1 ofObject: nameString withValue:
> (entryName at: i) asciiValue.
> - ].
> -
> - self storePointer: 0 ofObject: results withValue: nameString.
> - self storePointer: 1 ofObject: results withValue: createDateOop.
> - self storePointer: 2 ofObject: results withValue: modDateOop.
> - dirFlag
> - ifTrue: [ self storePointer: 3 ofObject: results
> withValue: trueObj ]
> - ifFalse: [ self storePointer: 3 ofObject: results
> withValue: falseObj ].
> - self storePointer: 4
> - ofObject: results
> - withValue: (self integerObjectOf: fileSize).
> - self storePointer: 5
> - ofObject: results
> - withValue: (self integerObjectOf: posixPermissions).
> -
> - ^ results
> - !
>
> Item was changed:
> ----- Method: SimpleStackBasedCogit>>genPrimitiveEqual (in category
> 'primitive generators') -----
> genPrimitiveEqual
> + ^self genSmallIntegerComparison: JumpZero
> + orDoubleComparison: #JumpFPEqual:
> + invert: false!
> - ^self genSmallIntegerComparison: JumpZero orDoubleComparison:
> #JumpFPEqual: asSymbol!
>
> Item was changed:
> ----- Method: SimpleStackBasedCogit>>genPrimitiveGreaterOrEqual (in
> category 'primitive generators') -----
> genPrimitiveGreaterOrEqual
> + ^self genSmallIntegerComparison: JumpGreaterOrEqual
> + orDoubleComparison: #JumpFPGreaterOrEqual:
> + invert: false!
> - ^self genSmallIntegerComparison: JumpGreaterOrEqual
> orDoubleComparison: #JumpFPGreaterOrEqual: asSymbol!
>
> Item was changed:
> ----- Method: SimpleStackBasedCogit>>genPrimitiveGreaterThan (in
> category 'primitive generators') -----
> genPrimitiveGreaterThan
> + ^self genSmallIntegerComparison: JumpGreater
> + orDoubleComparison: #JumpFPGreater:
> + invert: false!
> - ^self genSmallIntegerComparison: JumpGreater orDoubleComparison:
> #JumpFPGreater: asSymbol!
>
> Item was changed:
> ----- Method: SimpleStackBasedCogit>>genPrimitiveLessOrEqual (in
> category 'primitive generators') -----
> genPrimitiveLessOrEqual
> + ^self
> + genSmallIntegerComparison: JumpLessOrEqual
> + orDoubleComparison: #JumpFPGreater:
> + invert: true!
> - ^self genSmallIntegerComparison: JumpLessOrEqual
> orDoubleComparison: #JumpFPLessOrEqual: asSymbol!
>
???
Isn't this going to be a regression when comparing with NaN?
(2 <= Float nan) = false.
(2 > Float nan) not = true.
They are not equivalent and using inversion is not correct.
Or is nan handled elsewhere?
>
> Item was changed:
> ----- Method: SimpleStackBasedCogit>>genPrimitiveLessThan (in category
> 'primitive generators') -----
> genPrimitiveLessThan
> + ^self
> + genSmallIntegerComparison: JumpLess
> + orDoubleComparison: #JumpFPGreaterOrEqual:
> + invert: true!
> - ^self genSmallIntegerComparison: JumpLess orDoubleComparison:
> #JumpFPLess: asSymbol!
>
> Item was changed:
> ----- Method: SimpleStackBasedCogit>>genPrimitiveNotEqual (in category
> 'primitive generators') -----
> genPrimitiveNotEqual
> + ^self genSmallIntegerComparison: JumpNonZero
> + orDoubleComparison: #JumpFPNotEqual:
> + invert: false!
> - ^self genSmallIntegerComparison: JumpNonZero orDoubleComparison:
> #JumpFPNotEqual: asSymbol!
>
> Item was removed:
> - ----- Method:
> SimpleStackBasedCogit>>genSmallIntegerComparison:orDoubleComparison: (in
> category 'primitive generators') -----
> - genSmallIntegerComparison: jumpOpcode orDoubleComparison:
> jumpFPOpcodeGenerator
> - "Stack looks like
> - receiver (also in ResultReceiverReg)
> - arg
> - return address"
> - | jumpDouble jumpNonInt jumpFail jumpTrue jumpCond |
> - <var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction
> *(*jumpFPOpcodeGenerator)(void *)'>
> - <var: #jumpDouble type: #'AbstractInstruction *'>
> - <var: #jumpNonInt type: #'AbstractInstruction *'>
> - <var: #jumpCond type: #'AbstractInstruction *'>
> - <var: #jumpTrue type: #'AbstractInstruction *'>
> - <var: #jumpFail type: #'AbstractInstruction *'>
> - backEnd hasDoublePrecisionFloatingPointSupport ifFalse:
> - [^self genSmallIntegerComparison: jumpOpcode].
> - self genLoadArgAtDepth: 0 into: ClassReg.
> - jumpDouble := objectRepresentation genJumpNotSmallInteger:
> ClassReg scratchReg: TempReg.
> - self CmpR: ClassReg R: ReceiverResultReg. "N.B. FLAGS := RRReg -
> ClassReg"
> - jumpTrue := self gen: jumpOpcode.
> - self genMoveFalseR: ReceiverResultReg.
> - self RetN: (self primRetNOffsetFor: 1).
> - jumpTrue jmpTarget: (self genMoveTrueR: ReceiverResultReg).
> - self RetN: (self primRetNOffsetFor: 1).
> -
> - "Argument may be a Float : let us check or fail"
> - jumpDouble jmpTarget: self Label.
> - objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
> - [jumpNonInt := objectRepresentation genJumpImmediate:
> ClassReg].
> - objectRepresentation genGetCompactClassIndexNonImmOf: ClassReg
> into: SendNumArgsReg.
> - objectRepresentation genCmpClassFloatCompactIndexR: SendNumArgsReg.
> - jumpFail := self JumpNonZero: 0.
> -
> - "It was a Float, so convert the receiver to double and perform the
> operation"
> - self MoveR: ReceiverResultReg R: TempReg.
> - objectRepresentation genConvertSmallIntegerToIntegerInReg: TempReg.
> - self ConvertR: TempReg Rd: DPFPReg0.
> - objectRepresentation genGetDoubleValueOf: ClassReg into: DPFPReg1.
> - self CmpRd: DPFPReg1 Rd: DPFPReg0.
> - jumpCond := self perform: jumpFPOpcodeGenerator with: 0. "FP jumps
> are a little weird"
> - self genMoveFalseR: ReceiverResultReg.
> - self RetN: (self primRetNOffsetFor: 1).
> - jumpCond jmpTarget: (self genMoveTrueR: ReceiverResultReg).
> - self RetN: (self primRetNOffsetFor: 1).
> -
> - objectRepresentation smallIntegerIsOnlyImmediateType
> - ifTrue: [jumpFail jmpTarget: self Label]
> - ifFalse: [jumpNonInt jmpTarget: (jumpFail jmpTarget: self
> Label)].
> - ^0!
>
> Item was added:
> + ----- Method:
> SimpleStackBasedCogit>>genSmallIntegerComparison:orDoubleComparison:invert:
> (in category 'primitive generators') -----
> + genSmallIntegerComparison: jumpOpcode orDoubleComparison:
> jumpFPOpcodeGenerator invert: invertComparison
> + "Stack looks like
> + receiver (also in ResultReceiverReg)
> + arg
> + return address"
> + | jumpDouble jumpNonInt jumpFail jumpTrue jumpCond |
> + <var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction
> *(*jumpFPOpcodeGenerator)(void *)'>
> + <var: #jumpDouble type: #'AbstractInstruction *'>
> + <var: #jumpNonInt type: #'AbstractInstruction *'>
> + <var: #jumpCond type: #'AbstractInstruction *'>
> + <var: #jumpTrue type: #'AbstractInstruction *'>
> + <var: #jumpFail type: #'AbstractInstruction *'>
> + backEnd hasDoublePrecisionFloatingPointSupport ifFalse:
> + [^self genSmallIntegerComparison: jumpOpcode].
> + self genLoadArgAtDepth: 0 into: ClassReg.
> + jumpDouble := objectRepresentation genJumpNotSmallInteger:
> ClassReg scratchReg: TempReg.
> + self CmpR: ClassReg R: ReceiverResultReg. "N.B. FLAGS := RRReg -
> ClassReg"
> + jumpTrue := self gen: jumpOpcode.
> + self genMoveFalseR: ReceiverResultReg.
> + self RetN: (self primRetNOffsetFor: 1).
> + jumpTrue jmpTarget: (self genMoveTrueR: ReceiverResultReg).
> + self RetN: (self primRetNOffsetFor: 1).
> +
> + "Argument may be a Float : let us check or fail"
> + jumpDouble jmpTarget: self Label.
> + objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
> + [jumpNonInt := objectRepresentation genJumpImmediate:
> ClassReg].
> + objectRepresentation genGetCompactClassIndexNonImmOf: ClassReg
> into: SendNumArgsReg.
> + objectRepresentation genCmpClassFloatCompactIndexR: SendNumArgsReg.
> + jumpFail := self JumpNonZero: 0.
> +
> + "It was a Float, so convert the receiver to double and perform the
> operation"
> + self MoveR: ReceiverResultReg R: TempReg.
> + objectRepresentation genConvertSmallIntegerToIntegerInReg: TempReg.
> + self ConvertR: TempReg Rd: DPFPReg0.
> + objectRepresentation genGetDoubleValueOf: ClassReg into: DPFPReg1.
> + invertComparison "May need to invert for NaNs"
> + ifTrue: [self CmpRd: DPFPReg0 Rd: DPFPReg1]
> + ifFalse: [self CmpRd: DPFPReg1 Rd: DPFPReg0].
> + jumpCond := self perform: jumpFPOpcodeGenerator with: 0. "FP jumps
> are a little weird"
> + self genMoveFalseR: ReceiverResultReg.
> + self RetN: (self primRetNOffsetFor: 1).
> + jumpCond jmpTarget: (self genMoveTrueR: ReceiverResultReg).
> + self RetN: (self primRetNOffsetFor: 1).
> +
> + objectRepresentation smallIntegerIsOnlyImmediateType
> + ifTrue: [jumpFail jmpTarget: self Label]
> + ifFalse: [jumpNonInt jmpTarget: (jumpFail jmpTarget: self
> Label)].
> + ^0!
>
> Item was changed:
> ----- Method: StackInterpreter>>printStackPage: (in category 'debug
> printing') -----
> printStackPage: page
> + <inline: true>
> + self printStackPage: page useCount: -1!
> - <inline: false>
> - <var: #page type: #'StackPage *'>
> - self print: 'page '; printHexPtr: (self cCode: [page] inSmalltalk:
> [page baseAddress]);
> - print: ' ('; printNum: (stackPages pageIndexFor: page
> realStackLimit);
> - print: ') (trace: '; printNum: page trace; printChar: $).
> - (stackPages isFree: page) ifTrue:
> - [self print: ' (free)'].
> - page = stackPages mostRecentlyUsedPage ifTrue:
> - [self print: ' (MRU)'].
> - self cr; tab; print: 'ba: ';
> - printHexPtr: page baseAddress; print: ' - sl: ';
> - printHexPtr: page realStackLimit; print: ' - sl-so: ';
> - printHexPtr: page realStackLimit - self stackLimitOffset;
> print: ' - la:';
> - printHexPtr: page lastAddress.
> - (stackPages isFree: page) ifFalse:
> - [self cr; tab; print: 'baseFP '; printHexPtr: page baseFP.
> - self "cr;" tab; print: 'headFP '; printHexPtr: page
> headFP.
> - self "cr;" tab; print: 'headSP '; printHexPtr: page
> headSP].
> - self cr; tab; print: 'prev '; printHexPtr: (self cCode:
> 'page->prevPage' inSmalltalk: [page prevPage baseAddress]);
> - print: ' ('; printNum: (stackPages pageIndexFor: page
> prevPage realStackLimit); printChar: $).
> - self tab; print: 'next '; printHexPtr: (self cCode:
> 'page->nextPage' inSmalltalk: [page nextPage baseAddress]);
> - print: ' ('; printNum: (stackPages pageIndexFor: page
> nextPage realStackLimit); printChar: $).
> - self cr!
>
> Item was added:
> + ----- Method: StackInterpreter>>printStackPage:useCount: (in category
> 'debug printing') -----
> + printStackPage: page useCount: n
> + <inline: false>
> + <var: #page type: #'StackPage *'>
> + self print: 'page '; printHexPtr: (self cCode: [page] inSmalltalk:
> [page baseAddress]);
> + print: ' ('; printNum: (stackPages pageIndexFor: page
> realStackLimit).
> + n >= 0 ifTrue:
> + [self print: ','; printNum: n].
> + self print: ') (trace: '; printNum: page trace; printChar: $).
> + (stackPages isFree: page) ifTrue:
> + [self print: ' (free)'].
> + page = stackPages mostRecentlyUsedPage ifTrue:
> + [self print: ' (MRU)'].
> + page prevPage = stackPages mostRecentlyUsedPage ifTrue:
> + [self print: ' (LRU)'].
> + self cr; tab; print: 'ba: ';
> + printHexPtr: page baseAddress; print: ' - sl: ';
> + printHexPtr: page realStackLimit; print: ' - sl-so: ';
> + printHexPtr: page realStackLimit - self stackLimitOffset;
> print: ' - la:';
> + printHexPtr: page lastAddress.
> + (stackPages isFree: page) ifFalse:
> + [self cr; tab; print: 'baseFP '; printHexPtr: page baseFP.
> + self "cr;" tab; print: 'headFP '; printHexPtr: page
> headFP.
> + self "cr;" tab; print: 'headSP '; printHexPtr: page
> headSP].
> + self cr; tab; print: 'prev '; printHexPtr: (self cCode:
> 'page->prevPage' inSmalltalk: [page prevPage baseAddress]);
> + print: ' ('; printNum: (stackPages pageIndexFor: page
> prevPage realStackLimit); printChar: $).
> + self tab; print: 'next '; printHexPtr: (self cCode:
> 'page->nextPage' inSmalltalk: [page nextPage baseAddress]);
> + print: ' ('; printNum: (stackPages pageIndexFor: page
> nextPage realStackLimit); printChar: $).
> + self cr!
>
> Item was changed:
> ----- Method: StackInterpreter>>printStackPageListInUse (in category
> 'debug printing') -----
> printStackPageListInUse
> + | page n |
> - | page |
> <inline: false>
> <var: #page type: #'StackPage *'>
> page := stackPages mostRecentlyUsedPage.
> + n := 0.
> [(stackPages isFree: page) ifFalse:
> + [self printStackPage: page useCount: n; cr.
> + n := n + 1].
> - [self printStackPage: page.
> - self cr].
> (page := page prevPage) ~= stackPages mostRecentlyUsedPage]
> whileTrue!
>
> Item was changed:
> ----- Method: StackInterpreter>>printStackPagesInUse (in category 'debug
> printing') -----
> printStackPagesInUse
> + | n |
> + n := 0.
> 0 to: numStackPages - 1 do:
> [:i|
> (stackPages isFree: (stackPages stackPageAt: i)) ifFalse:
> + [self printStackPage: (stackPages stackPageAt: i)
> useCount: n; cr.
> + n := n + 1]]!
> - [self printStackPage: (stackPages stackPageAt: i).
> - self cr]]!
>
> Item was removed:
> - ----- Method:
> StackInterpreterSimulator>>makeDirEntryName:size:createDate:modDate:isDir:fileSize:posixPermissions:
> (in category 'file primitives') -----
> - makeDirEntryName: entryName size: entryNameSize createDate: createDate
> modDate: modifiedDate isDir: dirFlag fileSize: fileSize posixPermissions:
> posixPermissions
> - <option: #PharoVM>
> - <var: 'entryName' type: 'char *'>
> -
> - | modDateOop createDateOop nameString results |
> -
> - results := objectMemory instantiateClass:
> (objectMemory splObj: ClassArray) indexableSize: 5.
> - nameString := objectMemory instantiateClass:
> (objectMemory splObj: ClassString) indexableSize: entryNameSize.
> - createDateOop := self positive32BitIntegerFor: createDate.
> - modDateOop := self positive32BitIntegerFor: modifiedDate.
> -
> - 1 to: entryNameSize do:
> - [ :i |
> - objectMemory storeByte: i-1 ofObject: nameString
> withValue: (entryName at: i) asciiValue].
> -
> - objectMemory storePointerUnchecked: 0 ofObject: results withValue:
> nameString.
> - objectMemory storePointerUnchecked: 1 ofObject: results withValue:
> createDateOop.
> - objectMemory storePointerUnchecked: 2 ofObject: results withValue:
> modDateOop.
> - dirFlag
> - ifTrue: [ objectMemory storePointerUnchecked: 3 ofObject:
> results withValue: objectMemory trueObject ]
> - ifFalse: [ objectMemory storePointerUnchecked: 3 ofObject:
> results withValue: objectMemory falseObject ].
> - objectMemory storePointerUnchecked: 4 ofObject: results withValue:
> (objectMemory integerObjectOf: fileSize).
> - objectMemory storePointerUnchecked: 5 ofObject: results withValue:
> (objectMemory integerObjectOf: posixPermissions).
> - ^ results!
>
> Item was changed:
> ----- Method: StackInterpreterSimulator>>primitiveDirectoryEntry (in
> category 'file primitives') -----
> primitiveDirectoryEntry
> | name pathName array result |
> name := self stringOf: self stackTop.
> pathName := self stringOf: (self stackValue: 1).
>
> self successful ifFalse:
> [^self primitiveFail].
>
> array := FileDirectory default primLookupEntryIn: pathName name:
> name.
> array == nil ifTrue:
> [self pop: 3 thenPush: objectMemory nilObject.
> ^array].
> array == #badDirectoryPath ifTrue:
> [self halt.
> ^self primitiveFail].
>
> PharoVM
> ifTrue: [
> result := self makeDirEntryName: (array at: 1)
> size: (array at: 1) size
> createDate: (array at: 2) modDate: (array
> at: 3)
> isDir: (array at: 4) fileSize: (array at:
> 5)
> posixPermissions: (array at: 6) isSymlink:
> (array at: 7) ]
> ifFalse: [
> result := self makeDirEntryName: (array at: 1)
> size: (array at: 1) size
> createDate: (array at: 2) modDate: (array
> at: 3)
> isDir: (array at: 4) fileSize: (array at:
> 5) ].
> + self pop: 3 thenPush: result!
> - self pop: 3.
> - self push: result!
>
> Item was removed:
> - ----- Method:
> StackToRegisterMappingCogit>>genSmallIntegerComparison:orDoubleComparison:
> (in category 'primitive generators') -----
> - genSmallIntegerComparison: jumpOpcode orDoubleComparison:
> jumpFPOpcodeGenerator
> - "Stack looks like
> - return address"
> - | jumpDouble jumpNonInt jumpFail jumpTrue jumpCond |
> - <var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction
> *(*jumpFPOpcodeGenerator)(void *)'>
> - <var: #jumpDouble type: #'AbstractInstruction *'>
> - <var: #jumpNonInt type: #'AbstractInstruction *'>
> - <var: #jumpCond type: #'AbstractInstruction *'>
> - <var: #jumpTrue type: #'AbstractInstruction *'>
> - <var: #jumpFail type: #'AbstractInstruction *'>
> - backEnd hasDoublePrecisionFloatingPointSupport ifFalse:
> - [^self genSmallIntegerComparison: jumpOpcode].
> - jumpDouble := objectRepresentation genJumpNotSmallInteger: Arg0Reg
> scratchReg: TempReg.
> - self CmpR: Arg0Reg R: ReceiverResultReg. "N.B. FLAGS := RRReg -
> Arg0Reg"
> - jumpTrue := self gen: jumpOpcode.
> - self genMoveFalseR: ReceiverResultReg.
> - self RetN: 0.
> - jumpTrue jmpTarget: (self genMoveTrueR: ReceiverResultReg).
> - self RetN: 0.
> -
> - "Argument may be a Float : let us check or fail"
> - jumpDouble jmpTarget: self Label.
> - objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
> - [jumpNonInt := objectRepresentation genJumpImmediate:
> Arg0Reg].
> - objectRepresentation genGetCompactClassIndexNonImmOf: Arg0Reg
> into: SendNumArgsReg.
> - objectRepresentation genCmpClassFloatCompactIndexR: SendNumArgsReg.
> - jumpFail := self JumpNonZero: 0.
> -
> - "It was a Float, so convert the receiver to double and perform the
> operation"
> - objectRepresentation genConvertSmallIntegerToIntegerInReg:
> ReceiverResultReg.
> - self ConvertR: ReceiverResultReg Rd: DPFPReg0.
> - objectRepresentation genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
> - self CmpRd: DPFPReg1 Rd: DPFPReg0.
> - jumpCond := self perform: jumpFPOpcodeGenerator with: 0. "FP jumps
> are a little weird"
> - self genMoveFalseR: ReceiverResultReg.
> - self RetN: 0.
> - jumpCond jmpTarget: (self genMoveTrueR: ReceiverResultReg).
> - self RetN: 0.
> -
> - objectRepresentation smallIntegerIsOnlyImmediateType
> - ifTrue: [jumpFail jmpTarget: self Label]
> - ifFalse: [jumpNonInt jmpTarget: (jumpFail jmpTarget: self
> Label)].
> - ^0!
>
> Item was added:
> + ----- Method:
> StackToRegisterMappingCogit>>genSmallIntegerComparison:orDoubleComparison:invert:
> (in category 'primitive generators') -----
> + genSmallIntegerComparison: jumpOpcode orDoubleComparison:
> jumpFPOpcodeGenerator invert: invertComparison
> + "Stack looks like
> + return address"
> + | jumpDouble jumpNonInt jumpFail jumpTrue jumpCond |
> + <var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction
> *(*jumpFPOpcodeGenerator)(void *)'>
> + <var: #jumpDouble type: #'AbstractInstruction *'>
> + <var: #jumpNonInt type: #'AbstractInstruction *'>
> + <var: #jumpCond type: #'AbstractInstruction *'>
> + <var: #jumpTrue type: #'AbstractInstruction *'>
> + <var: #jumpFail type: #'AbstractInstruction *'>
> + backEnd hasDoublePrecisionFloatingPointSupport ifFalse:
> + [^self genSmallIntegerComparison: jumpOpcode].
> + jumpDouble := objectRepresentation genJumpNotSmallInteger: Arg0Reg
> scratchReg: TempReg.
> + self CmpR: Arg0Reg R: ReceiverResultReg. "N.B. FLAGS := RRReg -
> Arg0Reg"
> + jumpTrue := self gen: jumpOpcode.
> + self genMoveFalseR: ReceiverResultReg.
> + self RetN: 0.
> + jumpTrue jmpTarget: (self genMoveTrueR: ReceiverResultReg).
> + self RetN: 0.
> +
> + "Argument may be a Float : let us check or fail"
> + jumpDouble jmpTarget: self Label.
> + objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
> + [jumpNonInt := objectRepresentation genJumpImmediate:
> Arg0Reg].
> + objectRepresentation genGetCompactClassIndexNonImmOf: Arg0Reg
> into: SendNumArgsReg.
> + objectRepresentation genCmpClassFloatCompactIndexR: SendNumArgsReg.
> + jumpFail := self JumpNonZero: 0.
> +
> + "It was a Float, so convert the receiver to double and perform the
> operation"
> + objectRepresentation genConvertSmallIntegerToIntegerInReg:
> ReceiverResultReg.
> + self ConvertR: ReceiverResultReg Rd: DPFPReg0.
> + objectRepresentation genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
> + invertComparison "May need to invert for NaNs"
> + ifTrue: [self CmpRd: DPFPReg0 Rd: DPFPReg1]
> + ifFalse: [self CmpRd: DPFPReg1 Rd: DPFPReg0].
> + jumpCond := self perform: jumpFPOpcodeGenerator with: 0. "FP jumps
> are a little weird"
> + self genMoveFalseR: ReceiverResultReg.
> + self RetN: 0.
> + jumpCond jmpTarget: (self genMoveTrueR: ReceiverResultReg).
> + self RetN: 0.
> +
> + objectRepresentation smallIntegerIsOnlyImmediateType
> + ifTrue: [jumpFail jmpTarget: self Label]
> + ifFalse: [jumpNonInt jmpTarget: (jumpFail jmpTarget: self
> Label)].
> + ^0!
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20150807/271909d5/attachment-0001.htm
More information about the Vm-dev
mailing list