• Address Register Indirect with Index (8-Bit Displacement) Mode, huh yea

    From Tom Evans@21:1/5 to All on Fri Jan 1 23:23:25 2016
    To really abuse Edwin Starr's classic:

    Address Register Indirect with Index (8-Bit Displacement) Mode, huh yeah
    What is it good for?
    Absolutely nothing, oh hoh, oh
    Address Register Indirect with Index (8-Bit Displacement) Mode, huh yeah
    What is it good for?
    Absolutely nothing, say it again y'all

    http://www.metrolyrics.com/war-lyrics-edwin-starr.html

    This came up on the Freescale (now NXP)'s Coldfire Forum:

    https://community.freescale.com/thread/382391

    The classic 68k has the following addressing modes:

    2.2.7 Address Register Indirect with Index (8-Bit Displacement) Mode
    (d8, An, Xn.SIZE*SCALE)
    1 extension word
    2.2.8 Address Register Indirect with Index (Base Displacement) Mode
    (bd, An, Xn.SIZE*SCALE), bd can be 16 or 32 bits
    1, 2 or 3 extension words

    The second one looks useful. You can have "An" pointing to a structure and then address an indexed byte/word/long array using "Xn" at an offset of "bd" within that structure. Or use "Xn" to access an array of structures starting at "An" and use "bd" to
    get at structure elements.

    You can do the same with the first one, but the structure has to be smaller than 127 bytes. Which I'd think would limit its usefulness. Of course the compiler/programmer can always use the first for small stuff and use the second one when required.
    Unless it isn't there.

    The first one made it into the Coldfire. The second one didn't, due to the "maximum of two extension word limit" of the architecture.

    So is "(d8, An, Xn.SIZE*SCALE" of much use?

    Tom

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tom Evans@21:1/5 to Tom Evans on Tue Jan 19 19:27:30 2016
    On Saturday, January 2, 2016 at 6:23:25 PM UTC+11, Tom Evans wrote:
    So is "(d8, An, Xn.SIZE*SCALE" of much use?

    No responses and only 4 readers, depressing isn't it?

    Anyway I can answer this. That mode looks to be quite useful and well used.

    Disassembling a Coldfire bootstrap we have here that has 119k bytes of code in it consisting of about 34434 instructions:

    $ m68k-elf-objdump -S boot.elf | grep "@.*:" | grep -v pc | wc
    385 1930 21752

    $ m68k-elf-objdump -S boot.elf | grep "@.*:" | grep -v pc | less

    800006d6: 2191 0c00 movel %a1@,%a0@(00000000,%d0:l:4)
    800006f0: 2191 1c00 movel %a1@,%a0@(00000000,%d1:l:4)
    8000070a: 2191 0c08 movel %a1@,%a0@(00000008,%d0:l:4)
    8000073c: 2191 0c08 movel %a1@,%a0@(00000008,%d0:l:4)
    8000083a: 81b6 1ccc orl %d0,%fp@(ffffffcc,%d1:l:4)
    80000840: 3031 0a00 movew %a1@(00000000,%d0:l:2),%d0
    8000084a: 2d80 1ccc movel %d0,%fp@(ffffffcc,%d1:l:4)
    80000872: 1033 8800 moveb %a3@(00000000,%a0:l),%d0
    8000087e: 1233 8800 moveb %a3@(00000000,%a0:l),%d1
    8000088a: 1780 8800 moveb %d0,%a3@(00000000,%a0:l)
    80000a20: 4870 aa00 pea %a0@(00000000,%a2:l:2)
    80001316: 41f1 3c00 lea %a1@(00000000,%d3:l:4),%a0
    8000131c: 47f0 5800 lea %a0@(00000000,%d5:l),%a3
    80001346: 4872 0800 pea %a2@(00000000,%d0:l)
    800013bc: 41f1 1c0c lea %a1@(0000000c,%d1:l:4),%a0
    800013c0: 41f0 5800 lea %a0@(00000000,%d5:l),%a0
    8000168c: 52b6 0cec addql #1,%fp@(ffffffec,%d0:l:4)
    800016a2: 4ab6 0cec tstl %fp@(ffffffec,%d0:l:4)
    80001730: 4872 0800 pea %a2@(00000000,%d0:l)
    80001a02: 3031 0a00 movew %a1@(00000000,%d0:l:2),%d0
    80001a68: 41f1 2c00 lea %a1@(00000000,%d2:l:4),%a0
    80001a6c: 43f3 2a01 lea %a3@(00000001,%d2:l:2),%a1
    80001a70: 47f2 8800 lea %a2@(00000000,%a0:l),%a3
    80001a80: 2032 9a00 movel %a2@(00000000,%a1:l:2),%d0
    80002670: 2270 0800 moveal %a0@(00000000,%d0:l),%a1
    8000268c: cab0 0808 andl %a0@(00000008,%d0:l),%d5
    8000269a: b0b0 1c04 cmpl %a0@(00000004,%d1:l:4),%d0
    800027d4: c2b0 0808 andl %a0@(00000008,%d0:l),%d1
    800027e8: b2b0 0c04 cmpl %a0@(00000004,%d0:l:4),%d1
    80002802: 2430 2800 movel %a0@(00000000,%d2:l),%d2
    8000293e: c2b0 0808 andl %a0@(00000008,%d0:l),%d1
    80002952: b2b0 0c04 cmpl %a0@(00000004,%d0:l:4),%d1

    ... And about another 350 like that.

    The gcc compiler is making very good use of that instruction, most times just using it to add two registers together with a zero offset.

    And as for the normal (and way more popular) indexed ones:

    $ m68k-elf-objdump -S boot.elf | grep "@([0-9]*)" | wc
    5365 27050 238828

    m68k-elf-objdump -S boot.elf | grep "@([0-9]*)" | less

    800005ee: 4fef 000c lea %sp@(12),%sp
    80000690: 2f2e 0008 movel %fp@(8),%sp@-
    800006ae: 262e 0008 movel %fp@(8),%d3
    800006b2: 206a 0146 moveal %a2@(326),%a0
    800006ba: 2028 0004 movel %a0@(4),%d0
    800006d0: 43ee 0010 lea %fp@(16),%a1
    800006da: 43ee 0014 lea %fp@(20),%a1
    800006e0: 2828 0004 movel %a0@(4),%d4
    800006e4: 2228 0004 movel %a0@(4),%d1
    800006f4: 85a8 0188 orl %d2,%a0@(392)
    80000702: 43ee 000c lea %fp@(12),%a1
    80000706: 2141 0004 movel %d1,%a0@(4)
    8000071c: 41ea 014a lea %a2@(330),%a0
    80000722: 2028 0004 movel %a0@(4),%d0
    80000726: 2548 0146 movel %a0,%a2@(326)
    80000730: 2028 0004 movel %a0@(4),%d0
    80000734: 43ee 000c lea %fp@(12),%a1
    80000740: 85a8 018c orl %d2,%a0@(396)
    80000744: 2141 0004 movel %d1,%a0@(4)
    80000772: 20aa 0146 movel %a2@(326),%a0@
    80000778: 2548 0146 movel %a0,%a2@(326)
    8000077c: 42a8 0004 clrl %a0@(4)

    Count of normal "move" and "movea" instructions, and 26 "movec" ones:

    $ m68k-elf-objdump -S boot.elf | grep "move" | wc
    13940 65080 620299

    Tom

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)