English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 19 December 2020, 17:25   #1
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
gcc inline assembly

Does anyone have a set of decent examples for using inline assembly in gcc? It seems very fickle and I'm finding it difficult to pick out the relevant bits from the documentation, and the examples I've found on the web all seem too trivial.

I've got this far:

Code:
inline void Mult16x32(ULONG64 * result, WORD a, LONG b) {
    asm(
        "    mulsw   %2, %1\n" // 
        "\n" // something something with d0 and d1
        "    movel   %%d0, (%0)+\n"
        "    movel   %%d1, (%0)+\n"
        : // outputs
        : "a" (result), "d" (a), "d" (b) // inputs
        : "%d0", "%d1" // clobbers
    );
}
But it's taken a lot of trial and error to just get it to output legal code.
Ernst Blofeld is offline  
Old 19 December 2020, 17:32   #2
arcanist
Registered User
 
Join Date: Dec 2017
Location: Austin, TX
Age: 41
Posts: 405
I've only done a little bit, from here.

Code:
static WORD fix_mult(WORD a,
                     WORD b) {
  // Fixed-point multiplication with normalization for FFT.
  asm (
    "muls.w  %1,%0;"        // c = a*b
    "swap    %0;"           // c = a*b[15:0, 31:16]
    "rol.l   #1,%0;"        // c = a*b[14:0, 31, 30:15]
    "bpl     .no_carry_%=;" // branch if a*b[14] is 0
    "addq.w  #1,%0;"        // c = a*b[30:15] + a*b[14]
    ".no_carry_%=:;"
    : "+d"(a), "+d"(b)
  );

  return a;
}
arcanist is offline  
Old 19 December 2020, 17:40   #3
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
Quote:
Originally Posted by arcanist View Post
I've only done a little bit, from here.

Code:
static WORD fix_mult(WORD a,
                     WORD b) {
  // Fixed-point multiplication with normalization for FFT.
  asm (
    "muls.w  %1,%0;"        // c = a*b
    "swap    %0;"           // c = a*b[15:0, 31:16]
    "rol.l   #1,%0;"        // c = a*b[14:0, 31, 30:15]
    "bpl     .no_carry_%=;" // branch if a*b[14] is 0
    "addq.w  #1,%0;"        // c = a*b[30:15] + a*b[14]
    ".no_carry_%=:;"
    : "+d"(a), "+d"(b)
  );

  return a;
}
Cool, I'll check out the rest of your code too. Thanks.
Ernst Blofeld is offline  
Old 19 December 2020, 18:07   #4
Antiriad_UK
OCS forever!
 
Antiriad_UK's Avatar
 
Join Date: Mar 2019
Location: Birmingham, UK
Posts: 418
Yeah it's really tricky to understand. I did a couple for amigaklang and it took ages. Simple assembler function calls which I linked in.

Code:
// GCC Assembler syntax
// https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

// Install cia interrupt handler
void mt_install_cia(void)
{
	/* mt_install_cia(a6=CUSTOM, a0=VectorBase, d0=PALflag.b) */
	{
		register int _d0 asm("d0") = 1;
		register const void* _a0 asm("a0") = VBR;
		register const void* _a6 asm("a6") = (void*)0xdff000;

		asm volatile (
			"movem.l %%d0-%%d7/%%a0-%%a6,-(%%sp)\n"
			"jsr _mt_install_cia\n"
			"movem.l (%%sp)+,%%d0-%%d7/%%a0-%%a6"
			: 					// no outputs
			: "r" (_d0), "r" (_a0), "r" (_a6)	// inputs
			: "cc", "memory"			// changes memory and condition codes (can also put regs trashed here "d0", "d1")
			);
	}
}



UBYTE mt_getvumeter(void)
{
	UBYTE	mask = 0;

	{
		asm volatile (
			"move.b _mt_VUMeter,%0\n"
			"clr.b _mt_VUMeter"
			: "=g"(mask)				// outputs, g is any type of memory or register, "=" is "a variable overwriting an existing value"
			: 					// no inputs
			: "cc"					// condition codes trashed
			);
	}

	return mask;
}
Antiriad_UK is offline  
Old 19 December 2020, 18:25   #5
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
Quote:
Originally Posted by Antiriad_UK View Post
Yeah it's really tricky to understand. I did a couple for amigaklang and it took ages. Simple assembler function calls which I linked in.

Code:
// GCC Assembler syntax
// https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

// Install cia interrupt handler
void mt_install_cia(void)
{
	/* mt_install_cia(a6=CUSTOM, a0=VectorBase, d0=PALflag.b) */
	{
		register int _d0 asm("d0") = 1;
		register const void* _a0 asm("a0") = VBR;
		register const void* _a6 asm("a6") = (void*)0xdff000;

		asm volatile (
			"movem.l %%d0-%%d7/%%a0-%%a6,-(%%sp)\n"
			"jsr _mt_install_cia\n"
			"movem.l (%%sp)+,%%d0-%%d7/%%a0-%%a6"
			: 					// no outputs
			: "r" (_d0), "r" (_a0), "r" (_a6)	// inputs
			: "cc", "memory"			// changes memory and condition codes (can also put regs trashed here "d0", "d1")
			);
	}
}



UBYTE mt_getvumeter(void)
{
	UBYTE	mask = 0;

	{
		asm volatile (
			"move.b _mt_VUMeter,%0\n"
			"clr.b _mt_VUMeter"
			: "=g"(mask)				// outputs, g is any type of memory or register, "=" is "a variable overwriting an existing value"
			: 					// no inputs
			: "cc"					// condition codes trashed
			);
	}

	return mask;
}
In the mt_getvumeter example, what does the %0 refer to?
Ernst Blofeld is offline  
Old 19 December 2020, 20:36   #6
Antiriad_UK
OCS forever!
 
Antiriad_UK's Avatar
 
Join Date: Mar 2019
Location: Birmingham, UK
Posts: 418
%0 is the first output value which is “ "=g"(mask)”. And “mask” is the C variable name at the top of the function.

IIRC the numbers stack. So if you had 1 output value and 2 input values they would be %0 %1 and %2

Last edited by Antiriad_UK; 19 December 2020 at 20:49. Reason: Clarity
Antiriad_UK is offline  
Old 19 December 2020, 20:54   #7
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
Quote:
Originally Posted by Antiriad_UK View Post
%0 is the first output value which is “ "=g"(mask)”. And “mask” is the C variable name at the top of the function.

IIRC the numbers stack. So if you had 1 output value and 2 input values they would be %0 %1 and %2
Thank you, I have learnt something.
Ernst Blofeld is offline  
Old 20 December 2020, 01:59   #8
redblade
Zone Friend
 
redblade's Avatar
 
Join Date: Mar 2004
Location: Middle Earth
Age: 40
Posts: 2,127
https://www.cs.mcgill.ca/~cs573/fall...273/lecture17/

1998 McGill University, Interfacing GCC to 68k Assembler. It's 22 years old tho.
redblade is offline  
Old 20 December 2020, 14:25   #9
hooverphonique
ex. demoscener "Bigmama"
 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,624
Quote:
Originally Posted by Antiriad_UK View Post
%0 is the first output value which is “ "=g"(mask)”. And “mask” is the C variable name at the top of the function.

IIRC the numbers stack. So if you had 1 output value and 2 input values they would be %0 %1 and %2

It's also possible to use named arguments in place of %0, %1, etc:
Code:
"move.b mt_VUMeter,%[msk]\n"
: [msk] "=g" (mask)
hooverphonique is offline  
Old 20 December 2020, 16:21   #10
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
Quote:
Originally Posted by hooverphonique View Post
It's also possible to use named arguments in place of %0, %1, etc:
Code:
"move.b mt_VUMeter,%[msk]\n"
: [msk] "=g" (mask)
That is... sensible. I wonder why I've not seen it before.
Ernst Blofeld is offline  
Old 21 December 2020, 14:31   #11
Ernst Blofeld
<optimized out>
 
Ernst Blofeld's Avatar
 
Join Date: Sep 2020
Location: <optimized out>
Posts: 321
So, like this then?

Code:
inline LONG64 Mult16x32(const WORD a, const LONG b) {
    LONG64 result;

#ifndef __INTELLISENSE__
    asm(
        "   moveq   #1, %%d7                \n"

        "   movew   %[a], %%d0              \n"
        "   bge     1f                      \n"
        "   negw    %%d0                    \n"
        "   negw    %%d7                    \n"
        "1:                                 \n"

        "   movel   %[b], %%d1              \n"
        "   bge     2f                      \n"
        "   negl    %%d1                    \n"
        "   negw    %%d7                    \n"
        "2:                                 \n"

        "   movel   %%d1, %%d2              \n"
        "   swapw   %%d2                    \n"
        "   muluw   %%d0, %%d1              \n"
        "   muluw   %%d0, %%d2              \n"

        "   movel   %%d2, %%d0              \n"
        "   clrw    %%d0                    \n"
        "   swapw   %%d0                    \n"

        "   swapw   %%d2                    \n"
        "   clrw    %%d2                    \n"

        "   addl    %%d2, %%d1              \n"
        "   moveq   #0, %%d2                \n"
        "   addxl   %%d2, %%d0              \n"

        "   tstw    %%d7                    \n"
        "   bge     3f                      \n"
        "   negl    %%d1                    \n"
        "   negxl   %%d0                    \n"
        "3:                                 \n"

        "   lea     %[result], %%a0         \n"
        "   movel   %%d0, (%%a0)+           \n"
        "   movel   %%d1, (%%a0)+           \n"

        : // outputs
            [result] "=m" (result)

        : // inputs
            [a] "g" (a),
            [b] "g" (b)

        : // clobbers
            "cc", "%d0", "%d1", "%d2", "%d7", "%a0"
    );
#endif

    return result;
}
I'm still wondering if this could be efficiently written in C though, it's a shame to pollute my my lovely C code with dirty assembly just for this one thing.

Last edited by Ernst Blofeld; 21 December 2020 at 19:26.
Ernst Blofeld is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
how to rewrite particular asm inline syntax for gcc? wawa Coders. Asm / Hardware 44 15 February 2018 18:54
Inline ASM xArtx Coders. Asm / Hardware 10 27 July 2014 16:21
Converting assembly to C absence Coders. General 34 26 June 2010 09:17
Storm C V4...using inline assembler NovaCoder Coders. General 11 26 February 2009 12:10
assembly TV L8-X Amiga scene 2 04 August 2002 02:36

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 20:36.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.14507 seconds with 13 queries