Overview Features Coding ApolloOS Performance Forum Downloads Products Order Contact

Welcome to the Apollo Forum

This forum is for people interested in the APOLLO CPU.
Please read the forum usage manual.
Please visit our Apollo-Discord Server for support.



All TopicsNewsPerformanceGamesDemosApolloVampireAROSWorkbenchATARIReleases
Documentation about the Vampire hardware

68080 Assemblerpage  1 2 

Stefan "Bebbo" Franke

Posts 139
30 Sep 2019 21:35


is this correct assembled?
 

  foo:
          move.l  d1,d0
          move.l  d1,d8
          move.l  d1,d2
          move.l  d9,d2
          move.l  d3,d7
          move.l  d27,d31
          rts
 

  m68k-amigaos-as -m68080 foo.s -o foo.o
 

  foo:
    0:  2001            move.l d1,d0
    2:  7101            .short 0x7101
    4:  2001            move.l d1,d0
    6:  2401            move.l d1,d2
    8:  7104            .short 0x7104
    a:  2401            move.l d1,d2
    c:  2e03            move.l d3,d7
    e:  710f            .short 0x710f
    10:  2e03            move.l d3,d7
    12:  4e75            rts
 
 



Stefan "Bebbo" Franke

Posts 139
01 Oct 2019 18:24



          move.l  1( a2,  d3.l),2( a4,  a5.w)
          move.l  1( a2,  d3.l),2( a4, a13.w)
          move.l  1( a2,  d3.l),2(a12,  a5.w)
          move.l  1( a2, d11.l),2( a4,  a5.w)
          move.l  1(a10,  d3.l),2( a4,  a5.w)
          move.l  1(a10, d11.l),2(a12, a13.w)
 

  =>
 

    0:  29b2 3801 d002  move.l (1,a2,d3.l),(2,a4,a5.w)
    6:  7102            .short 0x7102
    8:  29b2 3801 d002  move.l (1,a2,d3.l),(2,a4,a5.w)
    e:  7101            .short 0x7101
  10:  29b2 3801 d002  move.l (1,a2,d3.l),(2,a4,a5.w)
  16:  7108            .short 0x7108
  18:  29b2 3801 d002  move.l (1,a2,d3.l),(2,a4,a5.w)
  1e:  7104            .short 0x7104
  20:  29b2 3801 d002  move.l (1,a2,d3.l),(2,a4,a5.w)
  26:  710f            .short 0x710f
  28:  29b2 3801 d002  move.l (1,a2,d3.l),(2,a4,a5.w)
 



Philippe Flype
(Apollo Team Member)
Posts 299
02 Oct 2019 07:44


Hello
 
You can compare with VASM assembler output, to be sure of the GCC output.
 
  EXTERNAL LINK   
  EXTERNAL LINK   
 
 
 
For convenience, you can use the -Fbin and -m68080 commandline argument
 
  EXTERNAL LINK   
  EXTERNAL LINK   
 


Stefan "Bebbo" Franke

Posts 139
02 Oct 2019 09:56


Thank you for that hint, unfortunately this does not work
 

      move.l d0,e0
 

  vasmm68k_mot -m68080  -Fhunk -phxass test.s -o test.o
 
  > error 9 in line 2 of "test.s": instruction not supported on selected architecture
  >      move.l  d0,e0
 
  same for  move.l d0,d8
 
 


Samuel Devulder

Posts 248
02 Oct 2019 13:53


It seem I get something by replacing "move.l d1,e0" with "load d1,e0". This probably not what you want, but it is a start. Notice that from vasm source it looks like -phxass only knows about 000-060:

  static int phxass_cpu_num(uint32_t type)
  {
    static int cpus[] = {
      68000,68010,68020,68030,68040,68060
    };
    int i;
 
    for (i=5; i>=0; i--)
      if (type & (1L<<i))
        return cpus;
 
    return 0;  /* not a cpu known to PhxAss, like for example ColdFire */
  }
 



Stefan "Bebbo" Franke

Posts 139
02 Oct 2019 14:16


Samuel Devulder wrote:

It seem I get something by replacing "move.l d1,e0" with "load d1,e0". This probably not what you want, but it is a start. Notice that from vasm source it looks like -phxass only knows about 000-060:

  static int phxass_cpu_num(uint32_t type)
  {
    static int cpus[] = {
      68000,68010,68020,68030,68040,68060
    };
    int i;
 
    for (i=5; i>=0; i--)
      if (type & (1L<<i))
        return cpus;
 
    return 0;  /* not a cpu known to PhxAss, like for example ColdFire */
  }
 

- omitting phxass does not make a difference.
- load d1,e0 is also working with phxass

unfortunately is 'load' using a different opcode which does not use a prepended 'bank' opcode.


Samuel Devulder

Posts 248
02 Oct 2019 16:22


Yeah "load" is somehow different than "move". Maybe Gunnar can explain ?
   
  Edit:
  1) there is no bug in the code quoted above with "return cpus;". It is cpus[ i ] acutally, but the i in square brackets is treated as an italic tag an doesn't show anything :) :)
 
  2) I have quickly browsed vasm source, and it didn't seem to output bank prefix (at first sight). With pure AMMX instructions like load/store/c2p/etc E0-E23 are accepted as register, but with std instructions, I wonder if VASM really is able to use E0-E23 regs in place of Dn regs.
 
  3) I wonder if "move.l 1(a10,  d3.l),2( a4,  a5.w)" is possible with BANK since a10 and d3 are both present in source but don't belong to the same register-bank.
 


Renee Cousins
(Apollo Team Member)
Posts 142
02 Oct 2019 21:58


Samuel Devulder wrote:

  Yeah "load" is somehow different than "move". Maybe Gunnar can explain ?

  MOVE is 32-bit and can be any-ea to any-ea. LOAD is 64-bit and is strictly ea to register. STORE is also 64-bit and is strictly register to ea. As far as I know, VASM does not support the BANK instruction; you have to use a MACRO and prefix everything manually yourself.
 
 


Samuel Devulder

Posts 248
02 Oct 2019 22:04


Also notice that BANK requires to know the size of the instruction it applies to. This probably explains why it isn't supported by VASM. It is too complex. Too bad :(


Stefan "Bebbo" Franke

Posts 139
03 Oct 2019 10:23


Renee Cousins wrote:

 
Samuel Devulder wrote:

    Yeah "load" is somehow different than "move". Maybe Gunnar can explain ?

    MOVE is 32-bit and can be any-ea to any-ea. LOAD is 64-bit and is strictly ea to register. STORE is also 64-bit and is strictly register to ea. As far as I know, VASM does not support the BANK instruction; you have to use a MACRO and prefix everything manually yourself.
 

 
  if you followed that reasoning, there'd only be macros. You use assembler so you don't need such macros^^. And the assembler knows the length of each encoded instruction, how else could it emit a correct byte stream?
 
 
  load/store are imho superfluous mnemonics. Also the apollo wiki says:
 

  MOVE
 
  Operation: Source -->; Destination
 
  Assembler Syntax: MOVE <ea>, <ea>
 
  Attributes: Size = (Byte, Word, Long, Quad)
 

 
  Are there separate mnemonics for the same action? /shrug
 
  Maybe there will be new mnemonics for add/sub with 64 bit? I recommend 'hin'/'wech' for the 64 bit operations...
 
  Also some new mnemonics are using the new registers directly - I wonder what happens if these are combined with a bank before.
 
  move is 8,16 or 32 bit, depending on .b,.w or .l
 
  68080 introduced 64 bit and the extension is --- who knows? vasm reports
 

  fatal error 2035 in line 4 of "test.s": illegal opcode extension
  >      abs.q  d0,b2
 

  So it isn't .q which is smart, since move.q vs. moveq will cause pita. But which one is it?
 
  === snip ===
  All I want is a working gas assembler for the 68080...
 
 
EDIT says: also the register names b0..b7 and e0..e23 aren't that smart. a8..15 and d8..d31 are more natural.
 
 


Gunnar von Boehn
(Apollo Team Member)
Posts 6207
03 Oct 2019 10:31


Stefan "Bebbo" Franke wrote:

      load/store are imho superfluous mnemonics.
     

   
There is a big difference between MOVE and LOAD/STORE
MOVE instruction alters/updates flags but LOAD and STORE does not
change flags!
 
Also the LOAD instruction does support "SPLAT" operation on immediates.
SPLAT operation means you can copy a 16bit immediate value into all 4 Word in the 64bit register.
SPLAT is a function which is supported by all AMMX instructions and is very often useful.
 
LOAD and STORE also support more features.
Some of them are LEGISTER-INDIRECT, another is STORE-WITH MASK.
 
Store with mask is very useful for certain operations.
The Mask is a Byte-Mask, it can be used for GFX operations.
Very useful for GFX writes useful for Sprite copies or for operations on 24bit screenmodes. 
 
With the MASK you can use store to do 1,2,3,4,5,6,7, or 8 BYTE moves.
   


Stefan "Bebbo" Franke

Posts 139
03 Oct 2019 11:49


Gunnar von Boehn wrote:

Stefan "Bebbo" Franke wrote:

        load/store are imho superfluous mnemonics.
     

   
  There is a big difference between MOVE and LOAD/STORE
  MOVE instruction alters/updates flags but LOAD and STORE does not
  change flags!
   
  Also the LOAD instruction does support "SPLAT" operation on immediates.
  SPLAT operation means you can copy a 16bit immediate value into all 4 Word in the 64bit register.
  SPLAT is a function which is supported by all AMMX instructions and is very often useful.
   
  LOAD and STORE also support more features.
  Some of them are LEGISTER-INDIRECT, another is STORE-WITH MASK.
 
  Store with mask is very useful for certain operations.
  The Mask is a Byte-Mask, it can be used for GFX operations.
  Very useful for GFX writes useful for Sprite copies or for operations on 24bit screenmodes. 
 
  With the MASK you can use store to do 1,2,3,4,5,6,7, or 8 BYTE moves.
   

understood!

And how do you emit a 64 bit move/add/sub/... ?



Samuel Crow

Posts 424
04 Oct 2019 04:56


Since AMMX is a 3 operand instruction set you can do a RISC style dummy operation for a move.


Samuel Devulder

Posts 248
04 Oct 2019 09:14


Move isn't the problem, there are a lot of equivalents. I think Bebbo's concernt is about 64bits arithmetics, and more generally how to use the extra regs on std instruction and <ea>.

The very first 2 questions of this thread: "is this correctly assembled?" hasn't received proper answer yet. I think this is a very, very, good question that deserve a proper response. Without it, it is likely that BANK, and indirectly all the extra regs will not be used by 68080-optimized code, which is a bit a waste of computing  resources IMHO.


Stefan "Bebbo" Franke

Posts 139
04 Oct 2019 09:44


Samuel Devulder wrote:

Move isn't the problem, there are a lot of equivalents. I think Bebbo's concernt is about 64bits arithmetics, and more generally how to use the extra regs on std instruction and <ea>.
 
  The very first 2 questions of this thread: "is this correctly assembled?" hasn't received proper answer yet. I think this is a very, very, good question that deserve a proper response. Without it, it is likely that BANK, and indirectly all the extra regs will not be used by 68080-optimized code, which is a bit a waste of computing  resources IMHO.

also the information how to save the new regs on the stack would be helpful:


  movem.l  d8/d9/a8/a9,-(sp)
...
  movem.l  (sp)+,d8/d9/a8/a9




Gunnar von Boehn
(Apollo Team Member)
Posts 6207
04 Oct 2019 10:37


Hi Bebbo

its great that you work on GCC.

Maybe the communication over this forum it not the most optimal solution right now.
I see here a little risk that something could be lost in translation.
Also there is a big delay as we are not read and answer immediately.
In regards of Instruction documentation I would propose to focus on our PDF/Excel files more than the HTML overview here as this might not be 100% update and also has no encodings listed.

And to improve the speed of communication maybe joining opur IRC channel might be better?
In IRC we can talk and brainstorm much faster.
Maybe even brainstorming and answering on phone will help us.

What do you think?



Gunnar von Boehn
(Apollo Team Member)
Posts 6207
05 Oct 2019 13:41


Hi Bebbo,

it was great talking to you on phone.

From our discussion about GCC and Register-Spill,
I got the impression that there is an encoding "hole" on 68K.
MOVEM is good to save several registers to stack.
But to save a single register there is no perfect instruction.
As the normal "move" alters the flags.

Did I understood you correct here?
Would a "PUSH/POP Dn" instruction help here?



Stefan "Bebbo" Franke

Posts 139
05 Oct 2019 17:34


Gunnar von Boehn wrote:

Hi Bebbo,
 
  it was great talking to you on phone.
 
  From our discussion about GCC and Register-Spill,
  I got the impression that there is an encoding "hole" on 68K.
  MOVEM is good to save several registers to stack.
  But to save a single register there is no perfect instruction.
  As the normal "move" alters the flags.
 
  Did I understood you correct here?
  Would a "PUSH/POP Dn" instruction help here?
 

Hi Gunnar,

it was a pleasure chatting with you.

The gap in the coding unfortunately exists since the 68k was born. Well, it's not exactly a gap since you could use movem instead of move, but that's slower and doubles the size. So IMHO an acceptable CCmode solution for the 68k must not use movem for spilling.

Thus there is no need of a special push/pop for the 68080, since the problem must be solved for whole 68k family. Don't waste your time with this.




Gunnar von Boehn
(Apollo Team Member)
Posts 6207
06 Oct 2019 09:47


Stefan "Bebbo" Franke wrote:

  The gap in the coding unfortunately exists since the 68k was born. Well, it's not exactly a gap since you could use movem instead of move, but that's slower and doubles the size. So IMHO an acceptable CCmode solution for the 68k must not use movem for spilling.
 

 
A user spoke to me about the following.
There was a function returning a value in D0
but also by coincident setting the flags according to it.
 

int function bla()[
    some work
    return true;
}

 
Depending on how the spilling is done the flags are trashed or not.

In this case the topic was about legacy software
relying on the FLAG behavior of an Amiga library -
and that if the library gets re-compiled with
a new GCC version the "side-effect" FLAG behavior did change ....




Stefan "Bebbo" Franke

Posts 139
06 Oct 2019 12:20


Gunnar von Boehn wrote:

  A user spoke to me about the following.
  There was a function returning a value in D0
  but also by coincident setting the flags according to it.
 
 

  int function bla()[
    some work
    return true;
  }
 

  Depending on how the spilling is done the flags are trashed or not.
 
  In this case the topic was about legacy software
  relying on the FLAG behavior of an Amiga library -
  and that if the library gets re-compiled with
  a new GCC version the "side-effect" FLAG behavior did change ....

The current ABI considers the status register as invalid after each call. And that won't change. Check e.g. the assembly of strncpy EXTERNAL LINK and you'll see that the flags do not match the value in d0.

If a user checks the flags instead without testing d0 (or whatever was returned) it's the user's problem.

posts 23page  1 2