Page 1 of 1

Convert Inline ASM to C Backend compatible code?

Posted: Fri Feb 11, 2022 12:31 am
by zikitrake
Hi, I would like to continue using this fantastic code from @Wilbert : https://www.purebasic.fr/english/viewtopic.php?t=66497

It has a part of inline ASM:

Code: Select all

    Procedure _PNGSizeCheck_(*MemoryAddress, MaxSize.l)
      EnableASM
      mov rdx, [p.p_MemoryAddress]
      !mov eax, [p.v_MaxSize]
      push rbx
      !lea ebx, [eax - 8]
      !xor eax, eax
      cmp dword [rdx], 0x474e5089
      !jne .l1
      cmp dword [rdx + 4], 0x0a1a0a0d
      !jne .l1
      !mov eax, 8
      !.l0:
      mov ecx, [rdx + rax]
      !bswap ecx
      lea rax, [rax + rcx + 12]
      !cmp eax, ebx
      !ja .l1
      cmp dword [rdx + rax + 4], 0x444e4549  
      !jne .l0
      !add eax, 12
      !.l1:
      pop rbx
      DisableASM
      ProcedureReturn
    EndProcedure
Is possible convert it to C backend compatible code without losing speed?

Thank you in advance!

Re: Convert Inline ASM to C Backend compatible code?

Posted: Fri Feb 11, 2022 1:54 pm
by juergenkulow
Please note:

Code: Select all

    ;- Macros (Windows)
    
    CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
      Macro rax : eax : EndMacro
      Macro rbx : ebx : EndMacro
      Macro rcx : ecx : EndMacro
      Macro rdx : edx : EndMacro
    CompilerEndIf  
and in IncludeFile "MemoryStreamModule.pbi"

Code: Select all

  Procedure.i MStream_AddRef(*this.MStream_Object)
    ; InterlockedIncrement of *this\refcount
    CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
      !mov edx, [p.p_this]
      !lock inc dword [edx + 4]
    CompilerElse
      !mov rdx, [p.p_this]
      !lock inc dword [rdx + 8]
    CompilerEndIf
    ProcedureReturn *this\refcount
  EndProcedure
  
  
  Procedure.i MStream_Release(*this.MStream_Object)
    ; InterlockedDecrement of *this\refcount
    CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
      !mov edx, [p.p_this]
      !lock dec dword [edx + 4]
    CompilerElse
      !mov rdx, [p.p_this]
      !lock dec dword [rdx + 8]
    CompilerEndIf
    ; Free memory if refcount = 0
    If *this\refcount = 0
      FreeMemory(*this)
      ProcedureReturn 0
    EndIf
    ProcedureReturn *this\refcount
  EndProcedure

Re: Convert Inline ASM to C Backend compatible code?

Posted: Sat Feb 12, 2022 3:06 pm
by zikitrake
juergenkulow wrote: Fri Feb 11, 2022 1:54 pm Please note:

Code: Select all

    ;- Macros (Windows)...
:oops: Thank you!I'll keep using the classic PB compiler then, which in the PB 6 version does the job as well as ever.

Re: Convert Inline ASM to C Backend compatible code?

Posted: Sat Feb 12, 2022 7:12 pm
by idle
Would be better to port it back to basic. I don't think we can have jmps with inline asm or maybe we can when it's at&t format. I tried yesterday but failed.

Re: Convert Inline ASM to C Backend compatible code?

Posted: Sat Feb 12, 2022 8:08 pm
by mk-soft
It also makes no sense to use ASM in the C-backend. This way, the code does not run on arm processors.

Re: Convert Inline ASM to C Backend compatible code?

Posted: Sat Feb 12, 2022 10:28 pm
by skywalk
I have a similar problem:

Code: Select all

Procedure RestoreX(DataLabel.i)
  CompilerSelect #PB_Compiler_Processor
  CompilerCase #PB_Processor_x64
    !MOV rax, [p.v_DataLabel]   ; instead of -> !MOV rax, [rsp+64]
    !MOV [PB_DataPointer], rax
  CompilerCase #PB_Processor_x86
    !MOV eax, [p.v_DataLabel]   ; instead of -> !MOV eax, [esp+8]
    !MOV [PB_DataPointer], eax
  CompilerDefault
      MessageRequester("RestoreX", "Unknown Processor.", #MB_ICONERROR)
  CompilerEndSelect
EndProcedure
; Example use within a procedure.
Procedure Do1()
  RestoreX(?ds_MyDatasectionStuff)
  Read.i i
EndProcedure

Re: Convert Inline ASM to C Backend compatible code?

Posted: Sun Feb 13, 2022 1:03 am
by idle
this will do it in c

Code: Select all

!*pb_datapointer = v_datalabel;

Re: Convert Inline ASM to C Backend compatible code?

Posted: Sun Feb 13, 2022 4:39 am
by skywalk
Thanks idle!
This got me close, but 1st data element is corrupted?
I posted the code here.

Re: Convert Inline ASM to C Backend compatible code?

Posted: Sun Feb 13, 2022 6:39 am
by breeze4me
It seems to work, but it is not thoroughly tested.

Code: Select all

Procedure _PNGSizeCheck_(*MemoryAddress, MaxSize)
  Protected result
  
  !__asm__ __volatile__ (".intel_syntax noprefix;"
  
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !"mov edx, %1;"
    !"mov eax, %2;"
    
    !"lea ebx, [eax - 8];"
    !"xor eax, eax;"
    ;!"xor ecx, ecx;"
    
    !"cmp dword ptr [edx], 0x474e5089;"
    !"jne locallabel_1;"
    
    !"cmp dword ptr [edx + 4], 0x0a1a0a0d;"
    !"jne locallabel_1;"
    
    !"mov eax, 8;"
    
    !"locallabel_0:;"
    !"mov ecx, dword ptr [edx + eax];"
    !"bswap ecx;"
    !"lea eax, [eax + ecx + 12];"
    
    !"cmp eax, ebx;"
    !"ja locallabel_1;"
    
    !"cmp dword ptr [edx + eax + 4], 0x444e4549;"
    !"jne locallabel_0;"
    !"add eax, 12;"
    
    !"locallabel_1:;"
    
    !"mov %[res], eax;"
    
    !".att_syntax"
    
    !: [res] "=r" (v_result)
    !: "r" (p_memoryaddress), "r" (v_maxsize)
    !: "edx", "eax", "ecx", "ebx"
    !);
    
  CompilerElse
    
    !"mov rdx, %1;"
    !"mov rax, %2;"
    
    !"lea rbx, [rax - 8];"
    !"xor rax, rax;"
    !"xor rcx, rcx;"
    
    !"cmp dword ptr [rdx], 0x474e5089;"
    !"jne locallabel_1;"
    
    !"cmp dword ptr [rdx + 4], 0x0a1a0a0d;"
    !"jne locallabel_1;"
    
    !"mov rax, 8;"
    
    !"locallabel_0:;"
    !"mov ecx, dword ptr [rdx + rax];"
    !"bswap ecx;"
    !"lea rax, [rax + rcx + 12];"
    
    !"cmp eax, ebx;"
    !"ja locallabel_1;"
    
    !"cmp dword ptr [rdx + rax + 4], 0x444e4549;"
    !"jne locallabel_0;"
    !"add rax, 12;"
    
    !"locallabel_1:;"
    
    !"mov %[res], rax;"
    
    !".att_syntax"
    
    !: [res] "=r" (v_result)
    !: "r" (p_memoryaddress), "r" (v_maxsize)
    !: "rdx", "rax", "rcx", "rbx"
    !);
  CompilerEndIf
  
  ProcedureReturn result
EndProcedure


Remove the macro.
;- Macros (Windows)

CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
Macro rax : eax : EndMacro
Macro rbx : ebx : EndMacro
Macro rcx : ecx : EndMacro
Macro rdx : edx : EndMacro
CompilerEndIf

Code: Select all

Procedure.i MStream_AddRef(*this.MStream_Object)
  ; InterlockedIncrement of *this\refcount
  
  ;*this\refcount + 1
  
  !__asm__ __volatile__ (".intel_syntax noprefix;"
  
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !"mov edx, %0;"
    !"lock inc dword ptr [edx + 4];"
    
    !".att_syntax"
    !:
    !: "r" (p_this)
    !: "edx"
    !);
    
  CompilerElse
    
    !"mov rdx, %0;"
    !"lock inc dword ptr [rdx + 8];"
    
    !".att_syntax"
    !:
    !: "r" (p_this)
    !: "rdx"
    !);
  CompilerEndIf
  
  ProcedureReturn *this\refcount
EndProcedure


Procedure.i MStream_Release(*this.MStream_Object)
  ; InterlockedDecrement of *this\refcount
  
  ;*this\refcount - 1
  
  !__asm__ __volatile__ (".intel_syntax noprefix;"
  
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !"mov edx, %0;"
    !"lock dec dword ptr [edx + 4];"
    
    !".att_syntax"
    !:
    !: "r" (p_this)
    !: "edx"
    !);
    
  CompilerElse
    
    !"mov rdx, %0;"
    !"lock dec dword ptr [rdx + 8];"
    
    !".att_syntax"
    !:
    !: "r" (p_this)
    !: "rdx"
    !);
  CompilerEndIf
  
  ; Free memory if refcount = 0
  If *this\refcount = 0
    FreeMemory(*this)
    
    ProcedureReturn 0
  EndIf
  
  ProcedureReturn *this\refcount
EndProcedure

Re: Convert Inline ASM to C Backend compatible code?

Posted: Sun Feb 13, 2022 12:59 pm
by zikitrake
breeze4me wrote: Sun Feb 13, 2022 6:39 am It seems to work, but it is not thoroughly tested....
I absolutely adore you :!: It seems to work like a charm :)

Sincerely, huge thanks to you and other users who make this forum so great.

Re: Convert Inline ASM to C Backend compatible code?

Posted: Sun Feb 13, 2022 4:11 pm
by wilbert
Thanks for converting.

I was wondering, does anyone know if the atomic function

Code: Select all

Procedure AtomicInc(*p.Integer)
  !return __atomic_add_fetch((int *)p_p, 1, __ATOMIC_RELAXED);
EndProcedure

AtomicInc(@v)
Debug v
is crossplatform and working on the arm version of macOS ?

Re: Convert Inline ASM to C Backend compatible code?

Posted: Sun Feb 13, 2022 9:14 pm
by idle
thanks breeze4me, I had an error in my code and thought there was something wrong using labels.