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

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

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

Igor Stasenko
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.

Reply | Threaded
Open this post in threaded view
|

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

Nicolas Cellier
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?

Nicolas

2011/5/11 Igor Stasenko <[hidden email]>:

> 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.
>
>

Reply | Threaded
Open this post in threaded view
|

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

Eliot Miranda-2


On Tue, May 10, 2011 at 11:11 PM, Nicolas Cellier <[hidden email]> 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 <[hidden email]>:
> 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.
>
>




Reply | Threaded
Open this post in threaded view
|

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

Gerardo Richarte
In reply to this post by Igor Stasenko
On 05/10/2011 08:34 PM, Igor Stasenko wrote:

> 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.
>
> They are mapping 1:1 to real registers on your machine.

"Our" names are pretty similar to those, and I don't really see they are
1:1 mapping to architecture (though at some point you will have that
mapping). The 1:1 mapping is not on names, but latter on implementation,
and I think that has to do with exactly what Cog wants: a fast
implementation.

FP is frame pointer, and it's the generic name for what in intel is BP
(in gdb you can do either $rbp or $fp)
SP is a generic name for the stack pointer (in gdb you can use $sp or $rsp)
ReceiverResult has to do with the use, nothing to do with processor
etc.

not sure what DPFPReg0 stands for.

I think the names are good for a VM implementation. Though maybe not for
a generic assembler. I think the that might be the difference between
Cog's and NativeBoost's needs

    gera

Reply | Threaded
Open this post in threaded view
|

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

Igor Stasenko
On 12 May 2011 17:22, Gerardo Richarte <[hidden email]> wrote:

> On 05/10/2011 08:34 PM, Igor Stasenko wrote:
>> 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.
>>
>> They are mapping 1:1 to real registers on your machine.
>
> "Our" names are pretty similar to those, and I don't really see they are
> 1:1 mapping to architecture (though at some point you will have that
> mapping). The 1:1 mapping is not on names, but latter on implementation,
> and I think that has to do with exactly what Cog wants: a fast
> implementation.
>

In Cog TempReg maps to EAX. and rest of register names mapped directly
to assembler ones.
I don't see how register names could affect an implementation.
It depends where and how you using them.
I agree that when you generating code which closely related to VM
internals, then it makes sense to use
special names like SendNumArgsReg. But if you wanna use spare register
to hold something else than
NumArgs.. then using such name is not helping.
In that cases, i would prefer to use neutral names, like
GPReg0 ... GPRegX .. which stands for General Purpose Register.
Because the role of certain register may be different depending on
where you using it.

> FP is frame pointer, and it's the generic name for what in intel is BP
> (in gdb you can do either $rbp or $fp)
> SP is a generic name for the stack pointer (in gdb you can use $sp or $rsp)
> ReceiverResult has to do with the use, nothing to do with processor
> etc.
>
> not sure what DPFPReg0 stands for.
>
I guess its a "Double Precision Floating Point Register number 0" :)

> I think the names are good for a VM implementation. Though maybe not for
> a generic assembler. I think the that might be the difference between
> Cog's and NativeBoost's needs
>

Yes. This is why i asking.. Because i want it to be generic.

>    gera
>


--
Best regards,
Igor Stasenko AKA sig.