inline asm c back end

Bare metal programming in PureBasic, for experienced users
User avatar
idle
Always Here
Always Here
Posts: 5039
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

inline asm c back end

Post by idle »

is it really going to be this easy to use asm inline with c back end?

Code: Select all

Procedure bswap(v.l) 
  Protected ret.l 
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    !".intel_syntax noprefix";
    !"mov eax, v_v";
    !"bswap eax"; 
    !"mov v_ret, eax";
  CompilerElse 
    !mov eax, [p.v_v]
    !bswap eax 
    !mov [p.v_ret],eax 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure 

x.i = $FF000000 
Debug RSet(Hex(x),8,"0")
x = bswap(x) 
Debug RSet(Hex(x),8,"0")

Edit: Answer no it's not, it wasn't working despite no compliant by the compiler.

Anyway here's an explanation of using asm templates.
https://www.felixcloutier.com/documents/gcc-asm.html

The statement structure boils down to this.
asm <optional stuff> (
"assembler template"
: outputs
: inputs
: clobbers
: labels)
so by following a output return variable pattern we can pretty much port existing asm without to much gnashing of teeth
Thanks Wilbert for a nudge in the right direction.

Code: Select all

; pbcompilerc -d test.pb
; pbcompiler -d test.pb

Macro AsmInput(var) 
  !:[var] "r" (v_#var) 
EndMacro  

Macro AsmInput2(var0,var1) 
  !:[var0] "r" (v_#var0),[var1] "r" (v_#var1) 
EndMacro  

Macro AsmInput3(var0,var1,var2) 
  !:[var0] "r" (v_#var0),[var1] "r" (v_#var1),[var2] "r" (v_#var2)  
EndMacro

Macro AsmOutput(var)
  !".att_syntax;"
  !:[var] "=r" (v_#var)
EndMacro
  
Macro BeginAsm() 
  !__asm__(
  !".intel_syntax noprefix;"
EndMacro

Macro EndAsm() 
  !);
EndMacro   

Procedure bswap(v.l) 
  Protected ret.l = 0  
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    BeginAsm()
    !"mov eax,%[v];"
    !"bswap eax;" 
    !"mov %[ret], eax;"
    AsmOutput(ret) 
    AsmInput(v)
    EndAsm()
  CompilerElse 
    !mov eax, [p.v_v]
    !bswap eax 
    !mov [p.v_ret],eax 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure 

Procedure shift_right(v.l, shift.l) 
  Protected ret.l =0
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    BeginAsm()
    !"mov eax,%[v];"
    !"mov ecx,%[shift];"
    !"shr eax,cl;"
    !"mov %[ret],eax;"
    AsmOutput(ret)
    AsmInput2(v,shift)
    EndAsm()
  CompilerElse 
    !mov eax, [p.v_v]
    !mov ecx, [p.v_shift]
    !shr eax, cl
    !mov [p.v_ret],eax 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure

Procedure absint(a.i)  
  Protected ret.i
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    BeginAsm()
    !"mov rdx,%[a];"
    !"mov rax, rdx;" 
    !"neg rax;"
    !"CMOVl rax,rdx;"
    !"mov %[ret],rax;" 
    AsmOutput(ret)
    AsmInput(a)
    EndAsm()
  CompilerElse
    !mov rdx,[p.v_a]
    !mov rax, rdx 
    !neg rax
    !CMOVl rax,rdx
    !mov [p.v_ret],rax 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure 

x.i = $FF000000 
Debug RSet(Hex(x),8,"0")
x= bswap(x) 
Debug RSet(Hex(x),8,"0")

x = absint(-42)
Debug x 

xx.l = $FF000000 
Debug RSet(Bin(xx, #PB_Long),32,"0")
xx = shift_right(xx, 1)
Debug RSet(Bin(xx, #PB_Long),32,"0")
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: inline asm c back end

Post by StarBootics »

I have try your code with the C backend and the compiler don't seem to complain but the swap is not working.
That being said the CPU I have in my computer is AMD Ryzen maybe that explain everything.

Fred himself said that inline assembler will be supported by the C backend compiler eventually not in version 6.00 but in the following one's and the ASM syntax will be little bit different.

But yeah, C compiler are capable to deal with ASM instructions.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
User avatar
idle
Always Here
Always Here
Posts: 5039
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: inline asm c back end

Post by idle »

Yes I was a bit fast in posting it as I assumed it worked when it didn't complain, but I didn't notice that it wasn't working.

maybe it just needs a flag passing onto gcc, I was under the impression that the inline asm with c instrisic's was working.
what I didn't know was that it could be done with little change.

it still doens't work the assembly is being parsed so I don't what's wrong here.?

Code: Select all

Procedure bswap(v.l) 
  Protected ret.l 
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    !".intel_syntax noprefix";
    !"mov eax, v_v";
    !"bswap eax"; 
    !"mov v_ret, eax";
  CompilerElse 
    !mov eax, [p.v_v]
    !bswap eax 
    !mov [p.v_ret],eax 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure 

x.i = $FF000000 
Debug RSet(Hex(x),8,"0")
x = bswap(x) 
Debug RSet(Hex(x),8,"0")



generates c

Code: Select all

// PureBasic 6.00 Beta 1 - C Backend (Linux - x64) generated code
// 
// (c) 2021 Fantaisie Software
// 
// The header must remain intact for Re-Assembly
// 
// :System
// 
#pragma warning(disable: 4024)
// 
typedef long long quad;
typedef quad integer;
#define PB_INFINITY (1.0 / 0.0)
#define PB_NEG_INFINITY (-1.0 / 0.0)
typedef struct pb_array { void *a; } pb_array;
typedef struct pb_array2 { void *a; integer b[2]; } pb_array2;
typedef struct pb_array3 { void *a; integer b[3]; } pb_array3;
typedef struct pb_array4 { void *a; integer b[4]; } pb_array4;
typedef struct pb_array5 { void *a; integer b[5]; } pb_array5;
typedef struct pb_array6 { void *a; integer b[6]; } pb_array6;
typedef struct pb_array7 { void *a; integer b[7]; } pb_array7;
typedef struct pb_array8 { void *a; integer b[8]; } pb_array8;
typedef struct pb_array9 { void *a; integer b[9]; } pb_array9;
typedef struct pb_listitem { void *a; void *b; void *c;} pb_listitem;
typedef struct pb_list { void *a; pb_listitem *b; } pb_list;
typedef struct pb_mapitem { void *a; void *b; void *c;} pb_mapitem;
typedef struct pb_pbmap { pb_mapitem *a; } pb_pbmap;
typedef struct pb_map { pb_pbmap *a; } pb_map;
static integer s_s[]={0, -1};
#define M_SYSFUNCTION(a) a
#define M_PBFUNCTION(a) a
#define M_CDECL
typedef void TCHAR;
static integer SYS_BankerRound    (double i) { return i >= 0 ? i+0.5 : i-0.5; }
static quad    SYS_BankerRoundQuad(double i) { return i >= 0 ? i+0.5 : i-0.5; }
// 
static char *tls;
int PB_ExitCode=0;
integer PB_MemoryBase=0;
integer PB_Instance=0;
int PB_ArgC;
char **PB_ArgV;
// 
// 
// 
// 
void SYS_Quit();
M_SYSFUNCTION(void) SYS_InitPureBasic();
int PB_DEBUGGER_LineNumber=-1;
int PB_DEBUGGER_IncludedFiles=0;
char *PB_DEBUGGER_FileName=0;
// 
static integer f_bswap(int v_v);

static integer ms_s[]={0,-1};
integer v_x=0;
// 
// 
// Procedure bswap(v.l) 
static integer f_bswap(int v_v) {
integer r=0;
int v_ret=0;
// Protected ret.l ;
// CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
// !".intel_syntax noprefix";
".intel_syntax noprefix";
// !"mov eax, v_v";
"mov eax, v_v";
// !"bswap eax"; 
"bswap eax"; 
// !"mov v_ret, eax";
"mov v_ret, eax";
// CompilerElse 
// ProcedureReturn ret 
r=v_ret;
goto end;
// EndProcedure 
end:
return r;
}
// 
char PB_OpenGLSubsystem=0;
int PB_Compiler_Unicode=1;
int PB_Compiler_Thread=0;
int PB_Compiler_Purifier=0;
int PB_Compiler_Debugger=0;
int PB_Compiler_DPIAware=0;
int PB_Compiler_XPSkins=0;
int PB_ExecutableType=0;
// 
void PB_EndFunctions() {
}
// 
int main(int argc, char* argv[]) {
PB_ArgC = argc;
PB_ArgV = argv;
SYS_InitPureBasic();
// 
// 
// x.i = $FF000000 
v_x=4278190080;
// Debug RSet(Hex(x),8,"0")
// x = bswap(x) 
integer rr0=f_bswap(v_x);
v_x=rr0;
// Debug RSet(Hex(x),8,"0")
// 
// 
SYS_Quit();
}

void SYS_Quit() {
PB_EndFunctions();
exit(PB_ExitCode);
}
User avatar
StarBootics
Addict
Addict
Posts: 984
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: inline asm c back end

Post by StarBootics »

The Stone Age did not end due to a shortage of stones !
User avatar
idle
Always Here
Always Here
Posts: 5039
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: inline asm c back end

Post by idle »

Yes those helped a bit. I suspect it's a compiler flag causing it to fail. The syntax is checked but the asm seems to be ignored. Ive asked Fred about it but tomorrow I will use a stub gcc to capture the command line used and see if I can fix it that way
It would be a huge time saver if we can use this asm format.
juergenkulow
Enthusiast
Enthusiast
Posts: 544
Joined: Wed Sep 25, 2019 10:18 am

Re: inline asm c back end

Post by juergenkulow »

Code: Select all

; Demo Problem with v_y and v_v in asm - any idea?   - only Windows x64 
Procedure.l bswap(v.l,w.l) 
  Protected y.l=v ;00000001400010AF | 8945 F8                  | mov dword ptr ss:[rbp-8],eax            |
;   	.align 8
; v_y:
; 	.space 8
; 	.text
  DisableDebugger
  CompilerIf Defined(PB_Compiler_Backend,#PB_Constant)
    CompilerIf #PB_Compiler_Backend = #PB_Backend_C
      ! asm("movl  16(%rbp),%eax\n\t bswap %eax \n\t movl %eax,24(%rbp)");
      
      ; ! asm("movl  -8(%rbp),%eax\n\t bswap %eax \n\t movl %eax,24(%rbp)"); 
      
      ; ! asm("movl  v_y(%rbp),%eax\n\t bswap %eax \n\t movl %eax,24(%rbp)"); 
      ; 00000001400010B2 | 8B85 30000000            | mov eax,dword ptr ss:[rbp+30]           |
      
      ; ! asm("movl  v_v(%rbp),%eax\n\t bswap %eax \n\t movl %eax,24(%rbp)"); 
      ; POLINK: error: Unresolved external symbol 'v_v' - referenced from 'PureBasic.obj'.
      
    CompilerElse 
      CompilerError "Only  #PB_Backend_C Testcode"
    CompilerEndIf 
  CompilerElse 
    CompilerError "Please use PB 6.00 Beta 1."
  CompilerEndIf 
  ProcedureReturn w
  EnableDebugger
EndProcedure 

x.i = $FF000000 
Debug RSet(Hex(x),16,"0")
x = bswap(x,y) 
Debug RSet(Hex(x),16,"0")

; 0000000140001090 | 55                       | push rbp                                |
; 0000000140001091 | 48:89E5                  | mov rbp,rsp                             |
; 0000000140001094 | 48:83EC 10               | sub rsp,10                              |
; 0000000140001098 | 894D 10                  | mov dword ptr ss:[rbp+10],ecx           |
; 000000014000109B | 8955 18                  | mov dword ptr ss:[rbp+18],edx           |
; 000000014000109E | C745 FC 00000000         | mov dword ptr ss:[rbp-4],0              |
; 00000001400010A5 | C745 F8 00000000         | mov dword ptr ss:[rbp-8],0              |
; 00000001400010AC | 8B45 10                  | mov eax,dword ptr ss:[rbp+10]           |
; 00000001400010AF | 8945 F8                  | mov dword ptr ss:[rbp-8],eax            |
; 00000001400010B2 | 8B45 F8                  | mov eax,dword ptr ss:[rbp-8]            |
; 00000001400010B5 | 0FC8                     | bswap eax                               |
; 00000001400010B7 | 8945 18                  | mov dword ptr ss:[rbp+18],eax           |
; 00000001400010BA | 8B45 18                  | mov eax,dword ptr ss:[rbp+18]           |
; 00000001400010BD | 8945 FC                  | mov dword ptr ss:[rbp-4],eax            |
; 00000001400010C0 | 90                       | nop                                     |
; 00000001400010C1 | 8B45 FC                  | mov eax,dword ptr ss:[rbp-4]            |
; 00000001400010C4 | 48:83C4 10               | add rsp,10                              |
; 00000001400010C8 | 5D                       | pop rbp                                 |
; 00000001400010C9 | C3                       | ret                                     |
juergenkulow
Enthusiast
Enthusiast
Posts: 544
Joined: Wed Sep 25, 2019 10:18 am

Re: inline asm c back end

Post by juergenkulow »

User avatar
idle
Always Here
Always Here
Posts: 5039
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: inline asm c back end

Post by idle »

Here's a good explanation of using asm templates.
https://www.felixcloutier.com/documents/gcc-asm.html

statement structure boils down to this.
asm <optional stuff> (
"assembler template"
: outputs
: inputs
: clobbers
: labels)
I've come up with these macros to make it a little easier to use intel syntax. Yes we need to modify our asm a little and follow a pattern returning through a variable rather than expecting to have a return on eax/rax
Procedure shift_right(v.l, shift.l)
Protected ret.l
BeginAsm()
!"mov eax,%[v];"
!"mov ecx,%[shift];"
!"shr eax,cl;"
!"mov %[ret],eax;"
AsmOutput(ret)
AsmInput2(v,shift)
EndAsm()
Test code

Code: Select all

Macro AsmInput(var) 
  !:[var] "r" (v_#var) 
EndMacro  

Macro AsmInput2(var0,var1) 
  !:[var0] "r" (v_#var0),[var1] "r" (v_#var1) 
EndMacro  

Macro AsmInput3(var0,var1,var2) 
  !:[var0] "r" (v_#var0),[var1] "r" (v_#var1),[var2] "r" (v_#var2)  
EndMacro

Macro AsmOutput(var)
  !".att_syntax;"
  !:[var] "=r" (v_#var)
EndMacro  
Macro BeginAsm() 
  !__asm__(
  !".intel_syntax noprefix;"
EndMacro

Macro BeginAsmGoto() 
  !asm goto(
  !".intel_syntax noprefix;"
EndMacro 
Macro EndAsm() 
  !);
EndMacro   

Procedure bswap(v.l) 
  Protected ret.l = 0  
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    BeginAsm()
    !"mov eax,%[v];"
    !"bswap eax;" 
    !"mov %[ret], eax;"
    AsmOutput(ret) 
    AsmInput(v)
    EndAsm()
  CompilerElse 
    !mov eax, [p.v_v]
    !bswap eax 
    !mov [p.v_ret],eax 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure 

Procedure shift_right(v.l, shift.l) 
  Protected ret.l =0
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    BeginAsm()
    !"mov eax,%[v];"
    !"mov ecx,%[shift];"
    !"shr eax,cl;"
    !"mov %[ret],eax;"
    AsmOutput(ret)
    AsmInput2(v,shift)
    EndAsm()
  CompilerElse 
    !mov eax, [p.v_v]
    !mov ecx, [p.v_shift]
    !shr eax, cl
    !mov [p.v_ret],eax 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure

Procedure absint(a.i)  
  Protected ret.i
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    BeginAsm()
    !"mov rdx,%[a];"
    !"mov rax, rdx;" 
    !"neg rax;"
    !"CMOVl rax,rdx;"
    !"mov %[ret],rax;" 
    AsmOutput(ret)
    AsmInput(a)
    EndAsm()
  CompilerElse
    !mov rdx,[p.v_a]
    !mov rax, rdx 
    !neg rax
    !CMOVl rax,rdx
    !mov [p.v_ret],rax 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure 

;-tests  
x.i = $FF000000 
Debug RSet(Hex(x),8,"0")
x= bswap(x) 
Debug RSet(Hex(x),8,"0")

x = absint(-42)
Debug x 

xx.l = $FF000000 
Debug RSet(Bin(xx, #PB_Long),32,"0")
xx = shift_right(xx, 1)
Debug RSet(Bin(xx, #PB_Long),32,"0")

User avatar
Lord
Addict
Addict
Posts: 847
Joined: Tue May 26, 2009 2:11 pm

Re: inline asm c back end

Post by Lord »

Are these results correct?

Code: Select all

Macro AsmInput(var) 
  !:[var] "r" (v_#var) 
EndMacro  

Macro AsmInput2(var0,var1) 
  !:[var0] "r" (v_#var0),[var1] "r" (v_#var1) 
EndMacro  

Macro AsmInput3(var0,var1,var2) 
  !:[var0] "r" (v_#var0),[var1] "r" (v_#var1),[var2] "r" (v_#var2)  
EndMacro

Macro AsmOutput(var)
  !".att_syntax;"
  !:[var] "=r" (v_#var)
EndMacro  
Macro BeginAsm() 
  !__asm__(
  !".intel_syntax noprefix;"
EndMacro

Macro BeginAsmGoto() 
  !asm goto(
  !".intel_syntax noprefix;"
EndMacro 
Macro EndAsm() 
  !);
EndMacro   

Procedure bswap(v.l) 
  Protected ret.l = 0  
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    BeginAsm()
    !"mov eax,%[v];"
    !"bswap eax;" 
    !"mov %[ret], eax;"
    AsmOutput(ret) 
    AsmInput(v)
    EndAsm()
  CompilerElse 
    !mov eax, [p.v_v]
    !bswap eax 
    !mov [p.v_ret],eax 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure 

Procedure shift_right(v.l, shift.l) 
  Protected ret.l =0
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    BeginAsm()
    !"mov eax,%[v];"
    !"mov ecx,%[shift];"
    !"shr eax,cl;"
    !"mov %[ret],eax;"
    AsmOutput(ret)
    AsmInput2(v,shift)
    EndAsm()
  CompilerElse 
    !mov eax, [p.v_v]
    !mov ecx, [p.v_shift]
    !shr eax, cl
    !mov [p.v_ret],eax 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure

Procedure absint(a.i)  
  Protected ret.i
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    BeginAsm()
    !"mov rdx,%[a];"
    !"mov rax, rdx;" 
    !"neg rax;"
    !"CMOVl rax,rdx;"
    !"mov %[ret],rax;" 
    AsmOutput(ret)
    AsmInput(a)
    EndAsm()
  CompilerElse
    !mov rdx,[p.v_a]
    !mov rax, rdx 
    !neg rax
    !CMOVl rax,rdx
    !mov [p.v_ret],rax 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure 

Procedure Tests(x)
Debug RSet(Hex(x),8,"0")
Debug RSet(Hex(absint(x)),8,"0")
b.s=RSet(Bin(x), 64, "0")
Debug Left(b, 16)+" "+Mid(b, 17, 16)+" "+Mid(b, 33, 16)+" "+Right(b, 16)
x= bswap(x) 
Debug RSet(Hex(x),8,"0")
Debug RSet(Hex(absint(x)),8,"0")
b.s=RSet(Bin(x), 64, "0")
Debug Left(b, 16)+" "+Mid(b, 17, 16)+" "+Mid(b, 33, 16)+" "+Right(b, 16)
Debug "----"
EndProcedure

;-tests  

x.i = $FF000000
Tests(x)

x.i = $00FF0000
Tests(x)

x.i = $0000FF00
Tests(x)

x.i = $000000FF
Tests(x)

x.i = $DEADBEEF 
Tests(x)

x.i = $DEAD0000 
Tests(x)

x.i = $0000BEEF 
Tests(x)
Image
User avatar
idle
Always Here
Always Here
Posts: 5039
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: inline asm c back end

Post by idle »

looks ok to me, the routines aren't of any significance as such, whats important is that the outputs are the same between fasm and gcc. The objective is to find a methodology which requires the least adaptation of existing asm. This is what I've got so far and I think its a fair compromise and easy enough to use, without much gnashing of teeth.

These are the results from my previous post
[idel@idle-pc PB]$ pbcompilerc -d junk6.pb
PureBasic 6.00 Beta 1 - C Backend (Linux - x64)

[Debugger] FF000000
[Debugger] 000000FF
[Debugger] 42
[Debugger] 11111111000000000000000000000000
[Debugger] 01111111100000000000000000000000

[idle@idle-pc PB]$ pbcompiler -d junk6.pb
PureBasic 6.00 Beta 1 (Linux - x64)

[Debugger] FF000000
[Debugger] 000000FF
[Debugger] 42
[Debugger] 11111111000000000000000000000000
[Debugger] 01111111100000000000000000000000
juergenkulow
Enthusiast
Enthusiast
Posts: 544
Joined: Wed Sep 25, 2019 10:18 am

Re: inline asm c back end

Post by juergenkulow »

Code: Select all

; bswap without Macros
Procedure bswap(v.l) 
  Protected ret.l  
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C 
    CompilerIf #PB_Processor_x64=#PB_Compiler_Processor Or #PB_Processor_x86=#PB_Compiler_Processor
      !__asm__(".intel_syntax noprefix;"
        !"mov eax,%[v];"
        !"bswap eax;" 
        !"mov %[ret], eax;"
        !".att_syntax prefix" 
      !:[ret] "=r" (v_ret) : [v] "r" (v_v)  );
    CompilerElseIf #PB_Processor_Arm64=#PB_Compiler_Processor
      CompilerError "No Arm64, M1 Code"
    CompilerElseIf #PB_Processor_Arm32=#PB_Compiler_Processor
      CompilerError "No Arm32 Code"
    CompilerEndIf 
  CompilerElse 
    CompilerError "C Backend Testcode only." 
  CompilerEndIf 
  ProcedureReturn ret 
EndProcedure 

;-tests  
x.i = $FF00EE11
s.s=RSet(Hex(x,#PB_Long),8,"0")+" "
x= bswap(x) 
; ! v_x=__builtin_bswap32(v_x); // With /OPTIMIZER on Windows x64 is one mov eax,eax faster.  
s+RSet(Hex(x,#PB_Long),8,"0")
Debug s
SetClipboardText(s) 
; FF00EE11 11EE00FF
User avatar
idle
Always Here
Always Here
Posts: 5039
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: inline asm c back end

Post by idle »

Thanks I will have to make a template out of the compiler if's. I doubt you'd notice any speed difference with just one additional mov and using the builtins will come in very useful to
Post Reply