HomeForumsWhat's newResources 
 
 
Inline Assembly
vbt - Jan 18, 2003
   vbt Jan 18, 2003 
I'm trying to learn by myself SH2 Assembly, but I don't understand something when I add a simple code into a C file, does someone has an idea ?

#define toto(value) asm volatile ( \

"add %1, %0 \n" /* add _F to _A */ \

"mov %0,%2 \n" /* put result into value */ \

:"=r" (value) /* _value as output : %2*/ \

:"r" (_A), /* _A as input : %0*/ \

"r" (_F) /* _F as input : %1*/ \

)


It seems that it adds _A and value instaed of adding _A to _F.

The result is correctly stored into value.

   antime Jan 18, 2003 
I'm no expert on GCC inline assembly, but I think that the register mapping is based on the order they're listed, ie. %0 refers to "value", %1 to "_A" and %2 to "_F".

EDIT: Should "_A" be added to the clobber list, as its value is modified?

   vbt Jan 18, 2003 
I wanted to put the result into "value" and you were right, the number corresponding to a parameter (input or output) is the order of these params. It was easier than thought (input param. then output params).

I don't know where I can find docs dealing with the use of assembly with GCC in a C code.

   AntiPasta Jan 18, 2003 
if you want to learn SH2 asm I think you'd better use SNASMSH2 like I do... then when you get a feel of the instruction set you could bother with the weird GCC syntax...

   antime Jan 18, 2003 

  
Originally posted by vbt@Jan. 18 2003, 11:55 pm

I don't know where I can find docs dealing with the use of assembly with GCC in a C code.


GCC's own manual has a section on it, titled Assembler Instructions with C Expression Operands..., but like most GNU manuals it's not as good as one would hope.

A couple of other links I managed to dig up:

http://www.cs.virginia.edu/~clc5q/gcc-inline-asm.p... combines a few popular docs on inline assembly. x86-oriented like most, unfortunately.

http://linuxassembly.org/... focuses on assembly programming for Linux.

http://www.egnite.de/ethernut/GCCAVRInlAsmCB.pdf... is a doc on using assembly in the AVR port of GCC. It differs a bit from mainstream GCC, but it seems like a pretty good document nevertheless.

http://www-106.ibm.com/developerworks/linu...brary... is IBM's tutorial on x86 assembly under Linux.

I'm still suspicious of _A being modified in your example, IMO it would be better written as

Code:
  
mov %1, %0 add %2, %0
which only modifies the output variable.

   vbt Jan 18, 2003 
Antime, you know too many doc. sites and your site is really great, I use it very often.

   vbt Mar 29, 2003 
Just a little question about Z80 ADD function, I wonder why SZ[(UINT8)res] var is no more used when this function is translated into assembly.

Code:
  
#define ADD(value) { unsigned val = value; \ unsigned res = _A + val; \ _F = SZ[(UINT8)res] | ((res >> 8) & CF) | \ ((_A ^ res ^ val) & HF) | \ (((val ^ _A ^ 0x80) & (val ^ res) & 0x80) >> 5); \ _A = (UINT8)res; \ } #define ADD(value) \ asm ( \ " addb %2,%0 \n" \ " lahf \n" \ " setob %1 \n" /* al = 1 if overflow */ \ " addb %1,%1 \n" \ " addb %1,%1 \n" /* shift to P/V bit position */ \ " andb $0xd1,%%ah \n" /* sign, zero, half carry, carry */ \ " orb %%ah,%1 \n" \ :"=q" (_A), "=q" (_F) \ :"q" (value), "1" (_F), "0" (_A) \ )

   antime Mar 29, 2003 
What core are you using? It's difficult to tell what's going on from just a partial snippet (ie. what is the array SZ used for?)

Two things though: bit-munging is much easier in assembler and sometimes it's easier to do a table look-up than to compute the value and secondly the Z80 flags are 1:1 reproducible in the x86 flags so if you do the same operations in x86 assembly you get the flags for "free" (remember that the two share a common ancestor, Intel's 8080).

   vbt Mar 29, 2003 
It's the Z80 core used by SMS plus and derived from MAME's Z80 core. Thanks for your answer it's really interesting. I need to learn more about Z80 internal core.

   AntiPasta Mar 29, 2003 
Z80 ASM is actually very easy and straightforward (although it is VERY different from SH2, but a lot like x86). I'd recommend you look here... (scroll to the bottom)

   TakaIsSilly Mar 29, 2003 
If i recall correctly, the MAME Z80 uses the SZ[] array to check if the zero/sign flag should activate.

The ASM core seems to retrieve that flag directly from of the CPU. In the SH-2 attempt I made, I used comparisations to set this flag.

As for the GCC syntax, is not that terrible. I learned to use it with little more than the as exceptions doc and the Hitachi SH-2 reference. Writing code worthwile, that's where the real deal is:

Code:
  
#define ADD(value) __asm__ volatile ( "shll16 %0 \n" "shll8 %0 \n" // placed just before the 32-bit boundary of the register "shll16 %2 \n" "shll8 %2 \n" // both _A and value suffer the change "mov %0,r1 \n" // temp store _A since we need to do add twice "addc %2,%0 \n" // add with carry. Carry stored in T "stc sr,r0 \n" // move sr to r0 "and #1,r0 \n" // Put _F 1 if T = 1 "or r0,%2 \n" // Set CARRY flag "mov r1,%0 \n" // get back the old _A value (we need r0) "addv %2,%0 \n" // Add again, but this time check for overflow "stc sr,r0 \n" // move sr to r0 "and #1,r0 \n" // Put _F 1 if T = 1 "shll2 r0 \n" // move the overflow flag to his correct location "or r0,%2 \n" // Set OVERFLOW flag "xor r1,r1 \n" // Clears r1, like we do with CISC "cmp/eq %0,r1 \n" // If _A is zero.... "stc sr,r0 \n" // move sr to r0 "and #1,r0 \n" // Clear all flags but T "shll8 r0 \n" "shlr2 r0 \n" // Moves 8-2 = 6 bit positions to the left "or r0,%2 \n" // OR's that value, 3 flags done (ZERO) "shlr16 %0 \n" "shlr8 %0 \n" // Reset all values back 24-bits "mov %0,r0 \n" // Moves the result into r0 for speed "and #128,r0 \n" // get the last bit "or r0,%2 \n" // put the result on F (SIGNAL) "shlr16 %2 \n" "shlr8 %2 \n" // both _A and value suffer the change :"=r" (_A), "=r" (_F) :"r" (value), "1" (_F), "0" (_A) )

You can replace it on the MAME core, and it will compile and run correctly on a SH-2. But it's 2 instructions slower than the C built code :/

   vbt Apr 20, 2003 
I tried to use this code instead of the C function but after that the emu seemed to be stucked

TakaIsSilly thanks again for your help