FAQ
Dear Gophers

I'm trying to use jump tables in 6a assembler files. Say I have a function
like this:

TEXT ·asmfunc(SB),7,$0

MOVQ $42, AX

// TODO: find jump target, move it to BX
// TODO: jump to address specified in BX

lab1:
MOVQ $43, AX

JMP funcend

lab2:
MOVQ $44, AX

JMP funcend

funcend:
MOVQ AX, r+0(FP)

RET


with the corresponding

func asmfunc() uint64


I want to put the addresses of the labels lab1, lab2 into a table so that I
can dispatch to one of them at the beginning of asmfunc. Unfortunately I
can't for the life of me figure out how to fill such a table with 6l. I
fail at the first step: taking the address of a label. Reading "A Manual
for the Plan 9 Assembler" I suspected it to be "$lab1<>+0(SB)", however
using this expression like in "MOVQ $lab1<>+0(SB), AX" I wind up with 6a
telling me "syntax error, last name: lab1".

Is what I try to achieve possible in 6a? What am I missing? ;)


Cheers,
distributed

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Ron minnich at Mar 18, 2013 at 8:41 pm
    anytime I need to do this sort of thing (and all us plan 9 guys have,
    over the years, with this toolchain) I write it in C, compile it, and
    see what I get. If I care I can optimize from there. But if you start
    with C, you get a lot of the bookkeeping bits right.

    So write it with a table of void *, and cast them to functions, and
    call them, and just in general lay the C out the way you want assembly
    to look, and it will make it easier. It has for me anyway.

    ron

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Distributed at Mar 18, 2013 at 9:53 pm
    This is a very useful suggestion. I will investigate the code that 6c
    generates for a corresponding C program.

    Just to be clear, it's not like I absolutely need the performance ;) I was
    just curious about how expensive certain parts of my interpreting 6502
    instruction set simulator are, and I was especially interested about the
    dispatcher :)

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Minux at Mar 18, 2013 at 8:45 pm

    On Tue, Mar 19, 2013 at 4:37 AM, distributed wrote:
    Dear Gophers

    I'm trying to use jump tables in 6a assembler files. Say I have a function
    like this:
    TEXT ·asmfunc(SB),7,$0

    MOVQ $42, AX


    // TODO: find jump target, move it to BX

    // TODO: jump to address specified in BX


    lab1:

    MOVQ $43, AX

    JMP funcend


    lab2:

    MOVQ $44, AX

    JMP funcend


    funcend:

    MOVQ AX, r+0(FP)

    RET

    with the corresponding
    func asmfunc() uint64

    I want to put the addresses of the labels lab1, lab2 into a table so that I
    can dispatch to one of them at the beginning of asmfunc. Unfortunately I
    can't for the life of me figure out how to fill such a table with 6l. I fail
    at the first step: taking the address of a label. Reading "A Manual for the
    Plan 9 Assembler" I suspected it to be "$lab1<>+0(SB)", however using this
    expression like in "MOVQ $lab1<>+0(SB), AX" I wind up with 6a telling me
    "syntax error, last name: lab1".
    i believe it's impossible to get the address of a label in plan 9 assembler (the
    object file simply doesn't allow that).

    however, you could define new function for each of your label as an approximate.

    TEXT ·asmfunc(SB),7,$0
    MOVQ $42, AX

    // TODO: find jump target, move it to BX
    // TODO: jump to address specified in BX

    TEXT lab1<>(SB),7,$0
    MOVQ $43, AX
    JMP funcend<>(SB)

    TEXT lab2<>(SB),7,$0
    MOVQ $44, AX
    JMP funcend<>(SB)

    TEXT funcend<>(SB),7,$0
    // blah blah

    DATA jumptable<>+0(SB)/8,$lab1<>(SB)
    DATA jumptable<>+8(SB)/8,$lab2<>(SB)

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Distributed at Mar 18, 2013 at 9:51 pm
    I started to fear that this is not possible ;)

    I tried the code you suggested, minux. The package go builds fine. However,
    I cannot build programs importing the package containing asmfunc, go build
    fails with "jumptable(51): not defined". I have no idea why the link step
    fails or what the 51 means.


    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Russ Cox at Mar 18, 2013 at 9:57 pm
    jump tables are not possible in the current object file format.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Distributed at Mar 18, 2013 at 10:28 pm
    Thanks for the confirmation. Out of curiosity, what about the current
    object file format prevents jump tables, missing relocation entries?

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Russ Cox at Mar 19, 2013 at 3:54 am
    There is no way to emit a data reference to a specific instruction within a
    function.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Michael Jones at Mar 19, 2013 at 4:01 am
    But you can easily have function dispatch tables. It costs you a call and a
    return, but the "dispatch" is an indexed load and very fast. My code does
    this.

    For example:

    func CountAndFrequencyForLength(base, length int) (count int, counts []int)
    {
    if base < 1 || length < 1 || length >= len(dispatchCFFL) {
    return simple.CountAndFrequencyForLength(base, length)
    }
    return dispatchCFFL[length](base)
    }

    // everything below this is autogenerated by the makefile

    var dispatchCFFL = []func(int) (int, []int){
    nil,
    countAndFrequencyForLength1,
    countAndFrequencyForLength2,
    countAndFrequencyForLength3,
    countAndFrequencyForLength4,
    countAndFrequencyForLength5,
    countAndFrequencyForLength6,
    countAndFrequencyForLength7,
    countAndFrequencyForLength8,
    countAndFrequencyForLength9,
    countAndFrequencyForLength10,
    countAndFrequencyForLength11,
    countAndFrequencyForLength12,
    countAndFrequencyForLength13,
    countAndFrequencyForLength14,
    countAndFrequencyForLength15,
    countAndFrequencyForLength16,
    countAndFrequencyForLength17,
    countAndFrequencyForLength18,
    countAndFrequencyForLength19,
    countAndFrequencyForLength20,
    countAndFrequencyForLength21,
    countAndFrequencyForLength22,
    countAndFrequencyForLength23,
    countAndFrequencyForLength24,
    countAndFrequencyForLength25,
    countAndFrequencyForLength26,
    countAndFrequencyForLength27,
    countAndFrequencyForLength28,
    countAndFrequencyForLength29,
    countAndFrequencyForLength30,
    countAndFrequencyForLength31,
    countAndFrequencyForLength32,
    }

    func countAndFrequencyForLength1(base int) (int, []int) {
    :
    return c, f
    }

    func countAndFrequencyForLength2(base int) (int, []int) {
    :
    return c, f
    }

    func countAndFrequencyForLength3(base int) (int, []int) {
    :
    return c, f
    }


    On Mon, Mar 18, 2013 at 8:54 PM, Russ Cox wrote:

    There is no way to emit a data reference to a specific instruction within
    a function.

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.



    --
    Michael T. Jones | Chief Technology Advocate | mtj@google.com | +1
    650-335-5765

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Distributed at Mar 19, 2013 at 7:59 am
    Thanks for the clarification.

    Michael, this is the implementation that I wanted to pitch the "naked" jump
    table against, except that I have no autogenerated parts. In my instruction
    set simulator I've got something like

    opdec := s6502tab[I]
    if opdec.Handler != nil {

    opdec.Handler(s, opdec.AddMode, I)

    return

    }
    with s being the CPU state.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Michael Jones at Mar 19, 2013 at 1:51 pm
    Looks good.

    "Labes as Values" is one of the great (i.e., helps me) extensions of GCC
    over K&R/ANSI C/C++ and is about doing just what you want. Behold:

    *Labels as Values*
    *================*
    *
    *
    * You can get the address of a label defined in the current function*
    *(or a containing function) with the unary operator `&&'. The value has*
    *type `void *'. This value is a constant and can be used wherever a*
    *constant of that type is valid. For example:*
    *
    *
    * void *ptr;*
    * ...*
    * ptr = &&foo;*
    *
    *
    * To use these values, you need to be able to jump to one. This is*
    *done with the computed goto statement(1), `goto *EXP;'. For example,*
    *
    *
    * goto *ptr;*
    *
    *
    *Any expression of type `void *' is allowed.*
    *
    *
    * One way of using these constants is in initializing a static array*
    *that will serve as a jump table:*
    *
    *
    * static void *array[] = { &&foo, &&bar, &&hack };*
    *
    *
    * Then you can select a label with indexing, like this:*
    *
    *
    * goto *array[i];*
    *
    *
    *Note that this does not check whether the subscript is in bounds--array*
    *indexing in C never does that.*
    *
    *
    * Such an array of label values serves a purpose much like that of the*
    *`switch' statement. The `switch' statement is cleaner, so use that*
    *rather than an array unless the problem does not fit a `switch'*
    *statement very well.*
    *
    *
    * Another use of label values is in an interpreter for threaded code.*
    *The labels within the interpreter function can be stored in the*
    *threaded code for super-fast dispatching.*
    *
    *
    * You may not use this mechanism to jump to code in a different*
    *function. If you do that, totally unpredictable things will happen.*
    *The best way to avoid this is to store the label address only in*
    *automatic variables and never pass it as an argument.*
    *
    *
    * An alternate way to write the above example is*
    *
    *
    * static const int array[] = { &&foo - &&foo, &&bar - &&foo,*
    * &&hack - &&foo };*
    * goto *(&&foo + array[i]);*
    *
    *
    *This is more friendly to code living in shared libraries, as it reduces*
    *the number of dynamic relocations that are needed, and by consequence,*
    *allows the data to be read-only.*
    *
    *
    * ---------- Footnotes ----------*
    *
    *
    * (1) The analogous feature in Fortran is called an assigned goto, but*
    *that name seems inappropriate in C, where one can do more than simply*
    *store label addresses in label variables.*

    *
    *
    This is EXTREMELY valuable. Good for 10-15% speedup.

    Michael


    On Tue, Mar 19, 2013 at 12:59 AM, distributed wrote:

    Thanks for the clarification.

    Michael, this is the implementation that I wanted to pitch the "naked"
    jump table against, except that I have no autogenerated parts. In my
    instruction set simulator I've got something like

    opdec := s6502tab[I]
    if opdec.Handler != nil {

    opdec.Handler(s, opdec.AddMode, I)

    return

    }
    with s being the CPU state.

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.



    --
    Michael T. Jones | Chief Technology Advocate | mtj@google.com | +1
    650-335-5765

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Lucio at Mar 19, 2013 at 3:55 pm
    So why did they have to add an operator (&&), what stopped them from merely
    using "&"? Seems gratuitous to me.

    Oops, off-topic!

    Lucio.
    On Tuesday, 19 March 2013 15:50:26 UTC+2, Michael Jones wrote:

    Looks good.

    "Labes as Values" is one of the great (i.e., helps me) extensions of GCC
    over K&R/ANSI C/C++ and is about doing just what you want. Behold:

    *Labels as Values*
    *================*
    *
    *
    * You can get the address of a label defined in the current function*
    *(or a containing function) with the unary operator `&&'. The value has*
    *type `void *'. This value is a constant and can be used wherever a*
    *constant of that type is valid. For example:*
    *
    *
    * void *ptr;*
    * ...*
    * ptr = &&foo;*
    *
    *
    * To use these values, you need to be able to jump to one. This is*
    *done with the computed goto statement(1), `goto *EXP;'. For example,*
    *
    *
    * goto *ptr;*
    *
    *
    *Any expression of type `void *' is allowed.*
    *
    *
    * One way of using these constants is in initializing a static array*
    *that will serve as a jump table:*
    *
    *
    * static void *array[] = { &&foo, &&bar, &&hack };*
    *
    *
    * Then you can select a label with indexing, like this:*
    *
    *
    * goto *array[i];*
    *
    *
    *Note that this does not check whether the subscript is in bounds--array*
    *indexing in C never does that.*
    *
    *
    * Such an array of label values serves a purpose much like that of the*
    *`switch' statement. The `switch' statement is cleaner, so use that*
    *rather than an array unless the problem does not fit a `switch'*
    *statement very well.*
    *
    *
    * Another use of label values is in an interpreter for threaded code.*
    *The labels within the interpreter function can be stored in the*
    *threaded code for super-fast dispatching.*
    *
    *
    * You may not use this mechanism to jump to code in a different*
    *function. If you do that, totally unpredictable things will happen.*
    *The best way to avoid this is to store the label address only in*
    *automatic variables and never pass it as an argument.*
    *
    *
    * An alternate way to write the above example is*
    *
    *
    * static const int array[] = { &&foo - &&foo, &&bar - &&foo,*
    * &&hack - &&foo };*
    * goto *(&&foo + array[i]);*
    *
    *
    *This is more friendly to code living in shared libraries, as it reduces*
    *the number of dynamic relocations that are needed, and by consequence,*
    *allows the data to be read-only.*
    *
    *
    * ---------- Footnotes ----------*
    *
    *
    * (1) The analogous feature in Fortran is called an assigned goto, but*
    *that name seems inappropriate in C, where one can do more than simply*
    *store label addresses in label variables.*

    *
    *
    This is EXTREMELY valuable. Good for 10-15% speedup.

    Michael



    On Tue, Mar 19, 2013 at 12:59 AM, distributed <distr...@gloenggi.ch<javascript:>
    wrote:
    Thanks for the clarification.

    Michael, this is the implementation that I wanted to pitch the "naked"
    jump table against, except that I have no autogenerated parts. In my
    instruction set simulator I've got something like

    opdec := s6502tab[I]
    if opdec.Handler != nil {

    opdec.Handler(s, opdec.AddMode, I)

    return

    }
    with s being the CPU state.

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/groups/opt_out.



    --
    Michael T. Jones | Chief Technology Advocate | m...@google.com<javascript:>
    +1 650-335-5765
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedMar 18, '13 at 8:37p
activeMar 19, '13 at 3:55p
posts12
users6
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase