Convert Inline ASM to C Backend compatible code?

Just starting out? Need help? Post your questions and find answers here.
zikitrake
Addict
Addict
Posts: 868
Joined: Thu Mar 25, 2004 2:15 pm
Location: Spain

Convert Inline ASM to C Backend compatible code?

Post 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!
PB 6.21 beta, PureVision User
juergenkulow
Enthusiast
Enthusiast
Posts: 581
Joined: Wed Sep 25, 2019 10:18 am

Re: Convert Inline ASM to C Backend compatible code?

Post 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
zikitrake
Addict
Addict
Posts: 868
Joined: Thu Mar 25, 2004 2:15 pm
Location: Spain

Re: Convert Inline ASM to C Backend compatible code?

Post 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.
PB 6.21 beta, PureVision User
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Convert Inline ASM to C Backend compatible code?

Post 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.
User avatar
mk-soft
Always Here
Always Here
Posts: 6209
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Convert Inline ASM to C Backend compatible code?

Post 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.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Convert Inline ASM to C Backend compatible code?

Post 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
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Convert Inline ASM to C Backend compatible code?

Post by idle »

this will do it in c

Code: Select all

!*pb_datapointer = v_datalabel;
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Convert Inline ASM to C Backend compatible code?

Post by skywalk »

Thanks idle!
This got me close, but 1st data element is corrupted?
I posted the code here.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Convert Inline ASM to C Backend compatible code?

Post 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
zikitrake
Addict
Addict
Posts: 868
Joined: Thu Mar 25, 2004 2:15 pm
Location: Spain

Re: Convert Inline ASM to C Backend compatible code?

Post 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.
PB 6.21 beta, PureVision User
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Convert Inline ASM to C Backend compatible code?

Post 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 ?
Last edited by wilbert on Mon Feb 14, 2022 2:38 pm, edited 1 time in total.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
idle
Always Here
Always Here
Posts: 5839
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Convert Inline ASM to C Backend compatible code?

Post by idle »

thanks breeze4me, I had an error in my code and thought there was something wrong using labels.
Post Reply