[squeak-dev] [NativeBoost] Need your ideas, what platform-neutral assembler syntax you would like to have

Eliot Miranda eliot.miranda at gmail.com
Wed May 11 16:40:26 UTC 2011


On Tue, May 10, 2011 at 11:11 PM, Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com> wrote:

> With a single API, when one will implement another processor
> instruction set, you'll win.
> The naming of registers is application dependent, but these are just
> constants.
> I wonder if Eliot gave a look at gcc?
>

Not really.  My naming is based on a) the approach to registers Peter
Deutsch invented for HPS, the VisualWorks VM, which supports an acceptably
efficient register-based calling convention for Smalltalk machine code, and
b) the x86 ABI which determines which registers are callee-saved,
caller-saved, scratch and the C result register.  One shouldn't consider the
register names used in the Cog JIT as general names; they're specific to the
calling convention implemented by the Cog JIT for Smalltalk execution.

HTH,
Eliot


>
> Nicolas
>
> 2011/5/11 Igor Stasenko <siguctua at gmail.com>:
> > Hi,
> >
> > i took a look at Cog's abstract opcode syntax.
> > Check the CogRTLOpcodes class>>initialize for description,
> > and check the Cogit category 'abstract instructions' at instance side
> > for actual syntax.
> >
> > Things i don't like: register naming.
> > In cog you should use following register names:
> >        FPReg := -1.
> >        SPReg := -2.
> >        ReceiverResultReg := GPRegMax := -3.
> >        TempReg := -4.
> >        ClassReg := -5.
> >        SendNumArgsReg := -6.
> >        Arg0Reg := -7.
> >        Arg1Reg := GPRegMin := -8.
> >        DPFPReg0 := -9.
> >        DPFPReg1 := -10.
> >        DPFPReg2 := -11.
> >        DPFPReg3 := -12.
> >        DPFPReg4 := -13.
> >        DPFPReg5 := -14.
> >        DPFPReg6 := -15.
> >        DPFPReg7 := -16.
> >
> > They are mapping 1:1 to real registers on your machine.
> > But while such names could make sense in some cases for Cog,
> > in NativeBoost using register named like SendNumArgsReg will be
> confusing..
> > Okay... actually this is not a big deal, i could always use aliases
> > with different names (suggestions?).
> >
> > But i would really like you opinion on Cog's native code syntax.
> > Here how the native code assembly looks in cog:
> >
> > genDoubleArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil
> >        "Receiver and arg in registers.
> >         Stack looks like
> >                return address"
> >        <var: #preOpCheckOrNil declareC: 'AbstractInstruction
> > *(*preOpCheckOrNil)(int rcvrReg, int argReg)'>
> >        | jumpFailClass jumpFailAlloc jumpFailCheck jumpSmallInt doOp |
> >        <var: #jumpFailClass type: #'AbstractInstruction *'>
> >        <var: #jumpFailAlloc type: #'AbstractInstruction *'>
> >        <var: #jumpSmallInt type: #'AbstractInstruction *'>
> >        <var: #jumpFailCheck type: #'AbstractInstruction *'>
> >        <var: #doOp type: #'AbstractInstruction *'>
> >        self MoveR: Arg0Reg R: TempReg.
> >        objectRepresentation genGetDoubleValueOf: ReceiverResultReg into:
> DPFPReg0.
> >        self MoveR: Arg0Reg R: ClassReg.
> >        jumpSmallInt := objectRepresentation
> genJumpSmallIntegerInScratchReg: TempReg.
> >        objectRepresentation genGetCompactClassIndexNonIntOf: Arg0Reg
> into:
> > SendNumArgsReg.
> >        self CmpCq: objectMemory classFloatCompactIndex R: SendNumArgsReg.
> >        jumpFailClass := self JumpNonZero: 0.
> >        objectRepresentation genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
> >        doOp := self Label.
> >        preOpCheckOrNil ifNotNil:
> >                [jumpFailCheck := self perform: preOpCheckOrNil with:
> DPFPReg0 with:
> > DPFPReg1].
> >        self gen: arithmeticOperator operand: DPFPReg1 operand: DPFPReg0.
> >        jumpFailAlloc := objectRepresentation
> >                                                genAllocFloatValue:
> DPFPReg0
> >                                                into: SendNumArgsReg
> >                                                scratchReg: ClassReg
> >                                                scratchReg: TempReg.
> >        self MoveR: SendNumArgsReg R: ReceiverResultReg.
> >        self RetN: 0.
> >        "We need to push the register args on two paths; this one and the
> > interpreter primitive path.
> >        But the interpreter primitive path won't unless
> regArgsHaveBeenPushed
> > is false."
> >        self assert: methodOrBlockNumArgs <= self numRegArgs.
> >        jumpFailClass jmpTarget: self Label.
> >        preOpCheckOrNil ifNotNil:
> >                [jumpFailCheck jmpTarget: jumpFailClass getJmpTarget].
> >        self genPushRegisterArgsForNumArgs: methodOrBlockNumArgs.
> >        jumpFailClass := self Jump: 0.
> >        jumpSmallInt jmpTarget: self Label.
> >        objectRepresentation genConvertSmallIntegerToIntegerInScratchReg:
> ClassReg.
> >        self ConvertR: ClassReg Rd: DPFPReg1.
> >        self Jump: doOp.
> >        jumpFailAlloc jmpTarget: self Label.
> >        self compileInterpreterPrimitive: (coInterpreter
> >
>      functionPointerForCompiledMethod: methodObj
> >
>      primitiveIndex: primitiveIndex).
> >        jumpFailClass jmpTarget: self Label.
> >        ^0
> >
> > And here an example of NativeBoost code:
> >
> > emitArgumentsCoercion: gen
> >        " input - none,
> >        output - an arguments array in remmappable oops stack top"
> >        | asm proxy args argOop i |
> >        asm := gen asm.
> >        proxy := gen proxy.
> >        args := gen reserveTemp.
> >        argOop := gen reserveTemp.
> >
> >        asm label: 'emitArgumentsCoercion>>'.
> >
> >        proxy createInstanceOf: Array size: (gen fnSpec arguments size).
> >        proxy pushRemappableOop: EAX.
> >
> >        i := 0.
> >        gen fnSpec arguments do: [:arg |
> >                arg type readOop: (EBP ptr + arg offset) generator: gen.
> >                asm mov: EAX to: argOop.
> >                proxy popRemappableOop.
> >                asm mov: EAX to: args.
> >                proxy storePointer: i ofObject: args withValue: argOop.
> >                i := i+1.
> >                proxy pushRemappableOop: args.
> >        ].
> >
> >        asm label: '<<emitArgumentsCoercion'.
> >
> >        gen releaseTemps: 2.
> >
> > The code is of course doing different things.. but these example is
> > actually to indicate a following observation:
> >
> > even when i will introduce platform-neutral code, in most cases
> > you won't see a pure assembly language, but instead you will see a mix
> > of usual smalltalk code and assembler.
> >
> > If you can see, in both examples above you see a direct instructions
> > intermixed with another methods.
> > And it is totally normal, because for obvious reasons, even for
> > assembler code, there are a lot of repetitious patterns,
> > and you refactor repetitive code into separate methods (a thing which
> > you normally do if you follow DRY principle).
> >
> > So, i mean: its okay. I could change the assembler syntax to anything.
> > But code will still be looking mostly the same,
> > for most of code-generation routines.
> > Of course, if you write a pure-assembly routine, it will be pure. But
> > in practice you won't do it too often,
> > because you can reuse stuff which already been done, or even use
> > higher-level abstract syntax (i have one somewhere in my garage ;).
> >
> > But still, question remains open: should i take a Cog's assembler
> > syntax as a base,
> > or create own?
> > The pro for Cog-syntax that if some day we move code generation from
> > VM level to language,
> > then we can just use existing code.
> >
> > But from another side, if i have tool which can produce a native code,
> > from VM's perspective its completely irrelevant , where this code
> > comes from and what assembler syntax were used to generate it.
> >
> > Also, we don't have to constrain ourselves, because Cog's assembler
> > (and its implementation) were designed by taking into account that it
> > should be translatable to C,
> > while in NB we're always could use tricks like #perform: and block
> > closures, which of course not available in slang.
> >
> > Sorry for long tiresome posts.. But i need your feedback and opinion.
> >
> > --
> > Best regards,
> > Igor Stasenko AKA sig.
> >
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20110511/1ec80ae3/attachment.htm


More information about the Squeak-dev mailing list