Documentation about the Vampire hardware |
|
---|
| | Stefan "Bebbo" Franke
Posts 142 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 142 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 142 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 142 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 142 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 6239 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 142 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 142 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 6239 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 6239 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 142 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 6239 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 142 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.
| |
|
|
|