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")
Anyway here's an explanation of using asm templates.
https://www.felixcloutier.com/documents/gcc-asm.html
The statement structure boils down to this.
so by following a output return variable pattern we can pretty much port existing asm without to much gnashing of teethasm <optional stuff> (
"assembler template"
: outputs
: inputs
: clobbers
: labels)
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")