Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2653.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.2653 Author: eem Time: 9 January 2020, 11:17:22.618284 am UUID: d2865fca-938a-40b1-be84-e527d64bac7d Ancestors: VMMaker.oscog-eem.2652 Cogit: Use LoadEffectiveAddressMw:r:R: in place of MoveR:R:, AddCq:R: in the remaining few places. Remove some now-inferred type declarations. CoInterpreter: change the argument names for the validation routinre introduced for the frame in spectors, to avoid a Slang clash. =============== Diff against VMMaker.oscog-eem.2652 =============== Item was changed: ----- Method: CogObjectRepresentationForSpur>>genGetActiveContextLarge:inBlock: (in category 'initialization') ----- genGetActiveContextLarge: isLarge inBlock: isInBlock "Create a trampoline to answer the active context that will answer it if a frame is already married, and create it otherwise. Assume numArgs is in SendNumArgsReg and ClassReg is free." | header slotSize jumpSingle loopHead jumpNeedScavenge continuation exit | - <var: #jumpNeedScavenge type: #'AbstractInstruction *'> - <var: #continuation type: #'AbstractInstruction *'> - <var: #jumpSingle type: #'AbstractInstruction *'> - <var: #loopHead type: #'AbstractInstruction *'> - <var: #exit type: #'AbstractInstruction *'> cogit MoveMw: FoxMethod r: FPReg R: ClassReg; TstCq: MFMethodFlagHasContextFlag R: ClassReg. jumpSingle := cogit JumpZero: 0. "jump if flag bit not set" cogit "since the flag bit was set, get the context in the receiver reg and return" MoveMw: FoxThisContext r: FPReg R: ReceiverResultReg; RetN: 0. jumpSingle jmpTarget: cogit Label. "OK, it doesn't exist; instantiate and initialize it" "set the hasContext flag; See CoInterpreter class>>initializeFrameIndices" cogit OrCq: MFMethodFlagHasContextFlag R: ClassReg; MoveR: ClassReg Mw: FoxMethod r: FPReg. "now get the home CogMethod into ClassReg and save for post-instantiation." isInBlock caseOf: { [InFullBlock] -> [cogit SubCq: 3 R: ClassReg]. "-3 is -(hasContext+isBlock) flags" [InVanillaBlock] -> [cogit SubCq: 3 R: ClassReg; "-3 is -(hasContext+isBlock) flags" MoveM16: 0 r: ClassReg R: TempReg; SubR: TempReg R: ClassReg]. [0] -> [cogit SubCq: 1 R: ClassReg]. "-1 is hasContext flag" }. "instantiate the context..." slotSize := isLarge ifTrue: [LargeContextSlots] ifFalse: [SmallContextSlots]. header := objectMemory headerForSlots: slotSize format: objectMemory indexablePointersFormat classIndex: ClassMethodContextCompactIndex. self flag: #endianness. cogit MoveAw: objectMemory freeStartAddress R: ReceiverResultReg. self genStoreHeader: header intoNewInstance: ReceiverResultReg using: TempReg. cogit LoadEffectiveAddressMw: (objectMemory smallObjectBytesForSlots: slotSize) r: ReceiverResultReg R: TempReg; MoveR: TempReg Aw: objectMemory freeStartAddress; CmpCq: objectMemory getScavengeThreshold R: TempReg. jumpNeedScavenge := cogit JumpAboveOrEqual: 0. "Now initialize the fields of the context. See CoInterpreter>>marryFrame:SP:copyTemps:" "sender gets frame pointer as a SmallInteger" continuation := cogit MoveR: FPReg R: TempReg. self genSetSmallIntegerTagsIn: TempReg. cogit MoveR: TempReg Mw: objectMemory baseHeaderSize + (SenderIndex * objectMemory bytesPerOop) r: ReceiverResultReg. "pc gets frame caller as a SmallInteger" cogit MoveMw: FoxSavedFP r: FPReg R: TempReg. self genSetSmallIntegerTagsIn: TempReg. cogit MoveR: TempReg Mw: objectMemory baseHeaderSize + (InstructionPointerIndex * objectMemory bytesPerOop) r: ReceiverResultReg. "Set the method field, freeing up ClassReg again, and frame's context field," cogit MoveMw: (cogit offset: CogMethod of: #methodObject) r: ClassReg R: TempReg; MoveR: TempReg Mw: objectMemory baseHeaderSize + (MethodIndex * objectMemory wordSize) r: ReceiverResultReg; MoveR: ReceiverResultReg Mw: FoxThisContext r: FPReg. "Now compute stack pointer; this is stackPointer (- 1 for return pc if a CISC) - framePointer - wordSize (1 each for saved pc, method, context, receiver) + 1 (1-relative) + numArgs" "TPR note - the code here is actually doing context stackPointer := ((((fp - sp) / wordSize) - [3|4]) + num args) asSmallInteger" cogit SubR: SPReg R: FPReg R: TempReg; "TempReg := FPReg - SPReg" LogicalShiftRightCq: self log2BytesPerWord R: TempReg; SubCq: (cogit backEnd hasLinkRegister ifTrue: [3] ifFalse: [4]) R: TempReg; AddR: SendNumArgsReg R: TempReg. self genConvertIntegerToSmallIntegerInReg: TempReg. cogit MoveR: TempReg Mw: objectMemory baseHeaderSize + (StackPointerIndex * objectMemory bytesPerOop) r: ReceiverResultReg. "Set closureOrNil to either the stacked receiver or nil" isInBlock > 0 ifTrue: [cogit + LoadEffectiveAddressMw: 2 r: SendNumArgsReg R: TempReg; "+2 for saved fp and saved pc" - MoveR: SendNumArgsReg R: TempReg; - AddCq: 2 R: TempReg; "+2 for saved fp and saved pc" MoveXwr: TempReg R: FPReg R: TempReg] ifFalse: [cogit genMoveNilR: TempReg]. cogit MoveR: TempReg Mw: objectMemory baseHeaderSize + (ClosureIndex * objectMemory bytesPerOop) r: ReceiverResultReg. "Set the receiver" cogit MoveMw: FoxMFReceiver r: FPReg R: TempReg; MoveR: TempReg Mw: objectMemory baseHeaderSize + (ReceiverIndex * objectMemory bytesPerOop) r: ReceiverResultReg. "Now copy the arguments. This is tricky because of the shortage of registers,. ClassReg ranges from 1 to numArgs (SendNumArgsReg), and from ReceiverIndex + 1 to ReceiverIndex + numArgs. 1 to: numArgs do: [:i| temp := longAt(FPReg + ((SendNumArgs - i + 2) * wordSize)). +2 for saved pc and savedfp longAtput(FPReg + FoxMFReceiver + (i * wordSize), temp)]" "TPR note: this is a prime candidate for passing off to the backend to do at least faintly optimal code" cogit MoveCq: 1 R: ClassReg. loopHead := cogit CmpR: SendNumArgsReg R: ClassReg. exit := cogit JumpGreater: 0. cogit MoveR: SendNumArgsReg R: TempReg; SubR: ClassReg R: TempReg; AddCq: 2 R: TempReg; "+2 for saved fp and saved pc" MoveXwr: TempReg R: FPReg R: TempReg; AddCq: ReceiverIndex + (objectMemory baseHeaderSize / objectMemory wordSize) R: ClassReg; "Now convert ClassReg from frame index to context index" MoveR: TempReg Xwr: ClassReg R: ReceiverResultReg; SubCq: ReceiverIndex + (objectMemory baseHeaderSize / objectMemory wordSize) - 1 R: ClassReg; "convert back adding 1 ;-)" Jump: loopHead. exit jmpTarget: cogit Label. "Finally nil or copy the non-argument temps. ClassReg := FPReg + FoxMFReceiver. SendNumArgsReg := SendNumArgsReg+ReceiverIndex. [ClassReg := ClassReg - wordSize. backEnd hasLinkRegister ifTrue: [SPReg <= ClassReg] ifFalse: [SPReg < ClassReg]] whileTrue: [receiver[SendNumArgsReg] := *ClassReg. SendNumArgsReg := SendNumArgsReg + 1]]" coInterpreter marryFrameCopiesTemps ifFalse: [cogit MoveCq: objectMemory nilObject R: TempReg]. + cogit LoadEffectiveAddressMw: FoxMFReceiver r: FPReg R: ClassReg. - cogit - MoveR: FPReg R: ClassReg; - AddCq: FoxMFReceiver R: ClassReg. cogit AddCq: ReceiverIndex + 1 + (objectMemory baseHeaderSize / objectMemory wordSize) R: SendNumArgsReg. "The receiver has already been set. If on a CISC there's a retpc for the trampoline call on top of stack; if on a RISC there isn't." loopHead := cogit SubCq: objectMemory wordSize R: ClassReg. cogit CmpR: ClassReg R: SPReg. + exit := cogit backEnd hasLinkRegister + ifTrue: [cogit JumpAbove: 0] + ifFalse: [cogit JumpAboveOrEqual: 0]. - cogit backEnd hasLinkRegister - ifTrue: [exit := cogit JumpAbove: 0] - ifFalse: [exit := cogit JumpAboveOrEqual: 0]. coInterpreter marryFrameCopiesTemps ifTrue: [cogit MoveMw: 0 r: ClassReg R: TempReg]. cogit MoveR: TempReg Xwr: SendNumArgsReg R: ReceiverResultReg; AddCq: 1 R: SendNumArgsReg; Jump: loopHead. exit jmpTarget: cogit Label. cogit RetN: 0. jumpNeedScavenge jmpTarget: cogit Label. cogit backEnd saveAndRestoreLinkRegAround: [cogit CallRT: ceScheduleScavengeTrampoline registersToBeSavedMask: (cogit registerMaskFor: ReceiverResultReg and: SendNumArgsReg and: ClassReg)]. cogit Jump: continuation. ^0! Item was changed: ----- Method: CogObjectRepresentationForSqueakV3>>genAllocFloatValue:into:scratchReg:scratchReg: (in category 'compile abstract instructions') ----- genAllocFloatValue: dpreg into: resultReg scratchReg: scratch1 scratchReg: scratch2 <returnTypeC: #'AbstractInstruction *'> | allocSize newFloatHeaderSansHash jumpFail | <var: #jumpFail type: #'AbstractInstruction *'> allocSize := objectMemory baseHeaderSize + (objectMemory sizeof: #double). newFloatHeaderSansHash := ((ClassFloatCompactIndex << objectMemory compactClassFieldLSB bitOr: (objectMemory formatOfClass: objectMemory classFloat)) bitOr: allocSize) bitOr: HeaderTypeShort. cogit MoveAw: objectMemory freeStartAddress R: resultReg. + cogit LoadEffectiveAddressMw: allocSize r: resultReg R: scratch1. - cogit MoveR: resultReg R: scratch1. - cogit AddCq: allocSize R: scratch1. cogit MoveAw: objectMemory scavengeThresholdAddress R: scratch2. cogit CmpR: scratch2 R: scratch1. jumpFail := cogit JumpAboveOrEqual: 0. cogit MoveR: resultReg R: scratch2. self flag: #newObjectHash. cogit AndCq: HashMaskUnshifted << objectMemory wordSize R: scratch2. cogit LogicalShiftLeftCq: HashBitsOffset - objectMemory wordSize R: scratch2. cogit OrCq: newFloatHeaderSansHash R: scratch2. cogit MoveR: scratch2 Mw: 0 r: resultReg. cogit MoveRd: dpreg M64: objectMemory baseHeaderSize r: resultReg. cogit MoveR: scratch1 Aw: objectMemory freeStartAddress. ^jumpFail! Item was changed: ----- Method: Cogit>>AddR:R:R: (in category 'abstract instructions') ----- AddR: addendReg R: badendReg R: destReg "destReg := addendReg + badendReg" <inline: false> <returnTypeC: #'AbstractInstruction *'> | first | - <var: 'first' type: #'AbstractInstruction *'> backEnd hasThreeAddressArithmetic ifTrue: [^self gen: AddRRR operand: addendReg operand: badendReg operand: destReg]. self assert: badendReg ~= destReg. first := self gen: MoveRR operand: addendReg operand: destReg. self gen: AddRR operand: badendReg operand: destReg. ^first! Item was changed: ----- Method: Cogit>>AndCq:R:R: (in category 'abstract instructions') ----- AndCq: quickConstant R: srcReg R: destReg <inline: false> <returnTypeC: #'AbstractInstruction *'> | first | - <var: 'first' type: #'AbstractInstruction *'> backEnd hasThreeAddressArithmetic ifTrue: [^self gen: AndCqRR quickConstant: quickConstant operand: srcReg operand: destReg]. srcReg = destReg ifTrue: + [^self gen: AndCqR quickConstant: quickConstant operand: destReg]. - [^self gen: AndCqR quickConstant: quickConstant operand: destReg.]. first := self gen: MoveRR operand: srcReg operand: destReg. self gen: AndCqR quickConstant: quickConstant operand: destReg. ^first! Item was changed: ----- Method: Cogit>>ArithmeticShiftRightCq:R:R: (in category 'abstract instructions') ----- ArithmeticShiftRightCq: quickConstant R: srcReg R: destReg "destReg := (signed)srcReg >> quickConstant" <inline: false> <returnTypeC: #'AbstractInstruction *'> | first | - <var: 'first' type: #'AbstractInstruction *'> backEnd hasThreeAddressArithmetic ifTrue: [^self gen: ArithmeticShiftRightCqRR operand: quickConstant operand: srcReg operand: destReg]. first := self gen: MoveRR operand: srcReg operand: destReg. self gen: ArithmeticShiftRightCqR operand: quickConstant operand: destReg. ^first! Item was changed: ----- Method: Cogit>>LogicalShiftLeftCq:R:R: (in category 'abstract instructions') ----- LogicalShiftLeftCq: quickConstant R: srcReg R: destReg "destReg := srcReg << quickConstant" <inline: false> <returnTypeC: #'AbstractInstruction *'> | first | - <var: 'first' type: #'AbstractInstruction *'> backEnd hasThreeAddressArithmetic ifTrue: [^self gen: LogicalShiftLeftCqRR operand: quickConstant operand: srcReg operand: destReg]. first := self gen: MoveRR operand: srcReg operand: destReg. self gen: LogicalShiftLeftCqR operand: quickConstant operand: destReg. ^first! Item was changed: ----- Method: Cogit>>LogicalShiftRightCq:R:R: (in category 'abstract instructions') ----- LogicalShiftRightCq: quickConstant R: srcReg R: destReg "destReg := (unsigned)srcReg >> quickConstant" <inline: false> <returnTypeC: #'AbstractInstruction *'> | first | - <var: 'first' type: #'AbstractInstruction *'> backEnd hasThreeAddressArithmetic ifTrue: [^self gen: LogicalShiftRightCqRR operand: quickConstant operand: srcReg operand: destReg]. first := self gen: MoveRR operand: srcReg operand: destReg. self gen: LogicalShiftRightCqR operand: quickConstant operand: destReg. ^first! Item was changed: ----- Method: Cogit>>SubR:R:R: (in category 'abstract instructions') ----- SubR: subReg R: fromReg R: destReg "destReg := fromReg - subReg" <inline: false> <returnTypeC: #'AbstractInstruction *'> | first | - <var: 'first' type: #'AbstractInstruction *'> backEnd hasThreeAddressArithmetic ifTrue: [^self gen: SubRRR operand: subReg operand: fromReg operand: destReg]. self assert: subReg ~= destReg. first := self gen: MoveRR operand: fromReg operand: destReg. self gen: SubRR operand: subReg operand: destReg. ^first! Item was changed: ----- Method: Cogit>>ZeroExtend16R:R: (in category 'abstract instructions') ----- ZeroExtend16R: reg1 R: reg2 <inline: true> <returnTypeC: #'AbstractInstruction *'> + backEnd canZeroExtend ifFalse: + [| first | + reg1 = reg2 + ifTrue: + [first := self LogicalShiftLeftCq: BytesPerWord * 8 - 16 R: reg1] + ifFalse: + [first := self MoveR: reg1 R: reg2. + self LogicalShiftLeftCq: BytesPerWord * 8 - 16 R: reg1]. + self LogicalShiftRightCq: BytesPerWord * 8 - 16 R: reg2. + ^first]. + ^self gen: ZeroExtend16RR operand: reg1 operand: reg2! - backEnd canZeroExtend - ifTrue: [^self gen: ZeroExtend16RR operand: reg1 operand: reg2] - ifFalse: - [| first | - reg1 = reg2 - ifTrue: - [first := self LogicalShiftLeftCq: BytesPerWord * 8 - 16 R: reg1] - ifFalse: - [first := self MoveR: reg1 R: reg2. - self LogicalShiftLeftCq: BytesPerWord * 8 - 16 R: reg1]. - self LogicalShiftRightCq: BytesPerWord * 8 - 16 R: reg2. - ^first]! Item was changed: ----- Method: Cogit>>ZeroExtend32R:R: (in category 'abstract instructions') ----- ZeroExtend32R: reg1 R: reg2 <inline: true> <returnTypeC: #'AbstractInstruction *'> + backEnd canZeroExtend ifFalse: + [| first | + reg1 = reg2 + ifTrue: + [first := self LogicalShiftLeftCq: 32 R: reg1] + ifFalse: + [first := self MoveR: reg1 R: reg2. + self LogicalShiftLeftCq: 32 R: reg1]. + self LogicalShiftRightCq: 32 R: reg2. + ^first]. + ^self gen: ZeroExtend32RR operand: reg1 operand: reg2! - backEnd canZeroExtend - ifTrue: [^self gen: ZeroExtend32RR operand: reg1 operand: reg2] - ifFalse: - [| first | - reg1 = reg2 - ifTrue: - [first := self LogicalShiftLeftCq: 32 R: reg1] - ifFalse: - [first := self MoveR: reg1 R: reg2. - self LogicalShiftLeftCq: 32 R: reg1]. - self LogicalShiftRightCq: 32 R: reg2. - ^first]! Item was changed: ----- Method: Cogit>>ZeroExtend8R:R: (in category 'abstract instructions') ----- ZeroExtend8R: reg1 R: reg2 <inline: true> <returnTypeC: #'AbstractInstruction *'> + backEnd canZeroExtend ifFalse: + [| first | + reg1 = reg2 + ifTrue: + [first := self LogicalShiftLeftCq: BytesPerWord * 8 - 8 R: reg1] + ifFalse: + [first := self MoveR: reg1 R: reg2. + self LogicalShiftLeftCq: BytesPerWord * 8 - 8 R: reg1]. + self LogicalShiftRightCq: BytesPerWord * 8 - 8 R: reg2. + ^first]. + ^self gen: ZeroExtend8RR operand: reg1 operand: reg2! - backEnd canZeroExtend - ifTrue: [^self gen: ZeroExtend8RR operand: reg1 operand: reg2] - ifFalse: - [| first | - reg1 = reg2 - ifTrue: - [first := self LogicalShiftLeftCq: BytesPerWord * 8 - 8 R: reg1] - ifFalse: - [first := self MoveR: reg1 R: reg2. - self LogicalShiftLeftCq: BytesPerWord * 8 - 8 R: reg1]. - self LogicalShiftRightCq: BytesPerWord * 8 - 8 R: reg2. - ^first]! Item was changed: ----- Method: Cogit>>generateCaptureCStackPointers: (in category 'initialization') ----- generateCaptureCStackPointers: captureFramePointer "Generate the routine that writes the current values of the C frame and stack pointers into variables. These are used to establish the C stack in trampolines back into the C run-time. This is a presumptuous quick hack for x86. It is presumptuous for two reasons. Firstly the system's frame and stack pointers may differ from those we use in generated code, e.g. on register-rich RISCs. Secondly the ABI may not support a simple frameless call as written here (for example 128-bit stack alignment on Mac OS X)." | startAddress | <inline: false> self allocateOpcodes: 32 bytecodes: 0. startAddress := methodZoneBase. "Must happen first; value may be used in accessing any of the following addresses" backEnd hasVarBaseRegister ifTrue: [self PushR: VarBaseReg; MoveCq: self varBaseAddress R: VarBaseReg]. captureFramePointer ifTrue: [self MoveR: FPReg Aw: self cFramePointerAddress]. "Capture the stack pointer prior to the call. If we've pushed VarBaseReg take that into account." (backEnd leafCallStackPointerDelta ~= 0 or: [backEnd hasVarBaseRegister]) ifTrue: + [self LoadEffectiveAddressMw: + (backEnd hasVarBaseRegister + ifTrue: [backEnd leafCallStackPointerDelta + objectMemory wordSize] + ifFalse: [backEnd leafCallStackPointerDelta]) + r: SPReg + R: TempReg. - [self MoveR: SPReg R: TempReg. - self AddCq: (backEnd hasVarBaseRegister - ifTrue: [backEnd leafCallStackPointerDelta + objectMemory wordSize] - ifFalse: [backEnd leafCallStackPointerDelta]) R: TempReg. self MoveR: TempReg Aw: self cStackPointerAddress] ifFalse: [self MoveR: SPReg Aw: self cStackPointerAddress]. backEnd hasVarBaseRegister ifTrue: [self PopR: VarBaseReg]. self RetN: 0. self outputInstructionsForGeneratedRuntimeAt: startAddress. processor flushICacheFrom: startAddress asUnsignedInteger to: methodZoneBase asUnsignedInteger. self recordGeneratedRunTime: 'ceCaptureCStackPointers' address: startAddress. ceCaptureCStackPointers := self cCoerceSimple: startAddress to: #'void (*)(void)'! Item was changed: ----- Method: SimpleStackBasedCogit>>genFastPrimTraceUsing:and: (in category 'primitive generators') ----- genFastPrimTraceUsing: r1 and: r2 "Suport for compileInterpreterPrimitive. Generate inline code so as to record the primitive trace as fast as possible." backEnd byteReadsZeroExtend ifFalse: [self MoveCq: 0 R: r2]. self MoveAb: coInterpreter primTraceLogIndexAddress R: r2. + self LoadEffectiveAddressMw: 1 r: r2 R: r1. - self MoveR: r2 R: r1. - self AddCq: 1 R: r1. self MoveR: r1 Ab: coInterpreter primTraceLogIndexAddress. methodLabel addDependent: (self annotateAbsolutePCRef: (self MoveCw: methodLabel asInteger R: r1)). self MoveMw: (self offset: CogMethod of: #selector) r: r1 R: TempReg. self MoveCw: coInterpreter primTraceLogAddress asInteger R: r1. self MoveR: TempReg Xwr: r2 R: r1! |
Free forum by Nabble | Edit this page |