x86-64 assembler embedded in Python

Overview

PeachPy logo

Portable Efficient Assembly Code-generator in Higher-level Python (PeachPy)

PeachPy License: Simplified BSD Travis-CI Build Status AppVeyor Build Status

PeachPy is a Python framework for writing high-performance assembly kernels.

PeachPy aims to simplify writing optimized assembly kernels while preserving all optimization opportunities of traditional assembly. Some PeachPy features:

  • Universal assembly syntax for Windows, Unix, and Golang assembly.
    • PeachPy can directly generate ELF, MS COFF and Mach-O object files and assembly listings for Golang toolchain
  • Automatic adaption of function to different calling conventions and ABIs.
    • Functions for different platforms can be generated from the same assembly source
    • Supports Microsoft x64 ABI, System V x86-64 ABI (Linux, OS X, and FreeBSD), Linux x32 ABI, Native Client x86-64 SFI ABI, Golang AMD64 ABI, Golang AMD64p32 ABI
  • Automatic register allocation.
    • PeachPy is flexible and lets mix auto-allocated and hardcoded registers in the same code.
  • Automation of routine tasks in assembly programming:
    • Function prolog and epilog and generated by PeachPy
    • De-duplication of data constants (e.g. Constant.float32x4(1.0))
    • Analysis of ISA extensions used in a function
  • Supports x86-64 instructions up to AVX-512 and SHA
    • Including 3dnow!+, XOP, FMA3, FMA4, TBM and BMI2.
    • Excluding x87 FPU and most system instructions.
    • Rigorously tested with auto-generated tests to produce the same opcodes as binutils.
  • Auto-generation of metadata files
    • Makefile with module dependencies (-MMD and -MF options)
    • C header for the generated functions
    • Function metadata in JSON format
  • Python-based metaprogramming and code-generation.
  • Multiplexing of multiple instruction streams (helpful for software pipelining).
  • Compatible with Python 2 and Python 3, CPython and PyPy.

Online Demo

You can try online demo on PeachPy.IO

Installation

PeachPy is actively developed, and thus there are presently no stable releases of 0.2 branch. We recommend that you use the master version:

pip install --upgrade git+https://github.com/Maratyszcza/PeachPy

Installation for development

If you plan to modify PeachPy, we recommend the following installation procedure:

git clone https://github.com/Maratyszcza/PeachPy.git
cd PeachPy
python setup.py develop

Using PeachPy as a command-line tool

# These two lines are not needed for PeachPy, but will help you get autocompletion in good code editors
from peachpy import *
from peachpy.x86_64 import *

# Lets write a function float DotProduct(const float* x, const float* y)

# If you want maximum cross-platform compatibility, arguments must have names
x = Argument(ptr(const_float_), name="x")
# If name is not specified, it is auto-detected
y = Argument(ptr(const_float_))

# Everything inside the `with` statement is function body
with Function("DotProduct", (x, y), float_,
  # Enable instructions up to SSE4.2
  # PeachPy will report error if you accidentially use a newer instruction
  target=uarch.default + isa.sse4_2):

  # Request two 64-bit general-purpose registers. No need to specify exact names.
  reg_x, reg_y = GeneralPurposeRegister64(), GeneralPurposeRegister64()

  # This is a cross-platform way to load arguments. PeachPy will map it to something proper later.
  LOAD.ARGUMENT(reg_x, x)
  LOAD.ARGUMENT(reg_y, y)

  # Also request a virtual 128-bit SIMD register...
  xmm_x = XMMRegister()
  # ...and fill it with data
  MOVAPS(xmm_x, [reg_x])
  # It is fine to mix virtual and physical (xmm0-xmm15) registers in the same code
  MOVAPS(xmm2, [reg_y])

  # Execute dot product instruction, put result into xmm_x
  DPPS(xmm_x, xmm2, 0xF1)

  # This is a cross-platform way to return results. PeachPy will take care of ABI specifics.
  RETURN(xmm_x)

Now you can compile this code into a binary object file that you can link into a program...

# Use MS-COFF format with Microsoft ABI for Windows
python -m peachpy.x86_64 -mabi=ms -mimage-format=ms-coff -o example.obj example.py
# Use Mach-O format with SysV ABI for OS X
python -m peachpy.x86_64 -mabi=sysv -mimage-format=mach-o -o example.o example.py
# Use ELF format with SysV ABI for Linux x86-64
python -m peachpy.x86_64 -mabi=sysv -mimage-format=elf -o example.o example.py
# Use ELF format with x32 ABI for Linux x32 (x86-64 with 32-bit pointer)
python -m peachpy.x86_64 -mabi=x32 -mimage-format=elf -o example.o example.py
# Use ELF format with Native Client x86-64 ABI for Chromium x86-64
python -m peachpy.x86_64 -mabi=nacl -mimage-format=elf -o example.o example.py

What else? You can convert the program to Plan 9 assembly for use with Go programming language:

# Use Go ABI (asm version) with -S flag to generate assembly for Go x86-64 targets
python -m peachpy.x86_64 -mabi=goasm -S -o example_amd64.s example.py
# Use Go-p32 ABI (asm version) with -S flag to generate assembly for Go x86-64 targets with 32-bit pointers
python -m peachpy.x86_64 -mabi=goasm-p32 -S -o example_amd64p32.s example.py

If Plan 9 assembly is too restrictive for your use-case, generate .syso objects which can be linked into Go programs:

# Use Go ABI (syso version) to generate .syso objects for Go x86-64 targets
# Image format can be any (ELF/Mach-O/MS-COFF)
python -m peachpy.x86_64 -mabi=gosyso -mimage-format=elf -o example_amd64.syso example.py
# Use Go-p32 ABI (syso version) to generate .syso objects for Go x86-64 targets with 32-bit pointers
# Image format can be any (ELF/Mach-O/MS-COFF)
python -m peachpy.x86_64 -mabi=gosyso-p32 -mimage-format=elf -o example_amd64p32.syso example.py

See examples for real-world scenarios of using PeachPy with make, nmake and go generate tools.

Using PeachPy as a Python module

When command-line tool does not provide sufficient flexibility, Python scripts can import PeachPy objects from peachpy and peachpy.x86_64 modules and do arbitrary manipulations on output images, program structure, instructions, and bytecodes.

PeachPy as Inline Assembler for Python

PeachPy links assembly and Python: it represents assembly instructions and syntax as Python classes, functions, and objects. But it also works the other way around: PeachPy can represent your assembly functions as callable Python functions!

from peachpy import *
from peachpy.x86_64 import *

x = Argument(int32_t)
y = Argument(int32_t)

with Function("Add", (x, y), int32_t) as asm_function:
    reg_x = GeneralPurposeRegister32()
    reg_y = GeneralPurposeRegister32()

    LOAD.ARGUMENT(reg_x, x)
    LOAD.ARGUMENT(reg_y, y)

    ADD(reg_x, reg_y)

    RETURN(reg_x)

python_function = asm_function.finalize(abi.detect()).encode().load()

print(python_function(2, 2)) # -> prints "4"

PeachPy as Instruction Encoder

PeachPy can be used to explore instruction length, opcodes, and alternative encodings:

from peachpy.x86_64 import *

ADD(eax, 5).encode() # -> bytearray(b'\x83\xc0\x05')

MOVAPS(xmm0, xmm1).encode_options() # -> [bytearray(b'\x0f(\xc1'), bytearray(b'\x0f)\xc8')]

VPSLLVD(ymm0, ymm1, [rsi + 8]).encode_length_options() # -> {6: bytearray(b'\xc4\xe2uGF\x08'),
                                                       #     7: bytearray(b'\xc4\xe2uGD&\x08'),
                                                       #     9: bytearray(b'\xc4\xe2uG\x86\x08\x00\x00\x00')}

Tutorials

Users

  • NNPACK -- an acceleration layer for convolutional networks on multi-core CPUs.
  • ChaCha20 -- Go implementation of ChaCha20 cryptographic cipher.
  • AEZ -- Go implemenetation of AEZ authenticated-encryption scheme.
  • bp128 -- Go implementation of SIMD-BP128 integer encoding and decoding.
  • go-marvin32 -- Go implementation of Microsoft's Marvin32 hash function.
  • go-highway -- Go implementation of Google's Highway hash function.
  • go-metro -- Go implementation of MetroHash function.
  • go-stadtx -- Go implementation of Stadtx hash function.
  • go-sip13 -- Go implementation of SipHash 1-3 function.
  • go-chaskey -- Go implementation of Chaskey MAC.
  • go-speck -- Go implementation of SPECK cipher.
  • go-bloomindex - Go implementation of Bloom-filter based search index.
  • go-groupvariant - SSE-optimized group varint integer encoding in Go.
  • Yeppp! performance library. All optimized kernels in Yeppp! are implemented in PeachPy (uses old version of PeachPy with deprecated syntax).

Peer-Reviewed Publications

  • Marat Dukhan "PeachPy: A Python Framework for Developing High-Performance Assembly Kernels", Python for High-Performance Computing (PyHPC) 2013 (slides, paper, code uses deprecated syntax)
  • Marat Dukhan "PeachPy meets Opcodes: Direct Machine Code Generation from Python", Python for High-Performance Computing (PyHPC) 2015 (slides, paper on ACM Digital Library).

Other Presentations

Dependencies

  • Nearly all instruction classes in PeachPy are generated from Opcodes Database
  • Instruction encodings in PeachPy are validated against binutils using auto-generated tests
  • PeachPy uses six and enum34 packages as a compatibility layer between Python 2 and Python 3

Acknowledgements

HPC Garage logo Georgia Tech College of Computing logo

This work is a research project at the HPC Garage lab in the Georgia Institute of Technology, College of Computing, School of Computational Science and Engineering.

The work was supported in part by grants to Prof. Richard Vuduc's research lab, The HPC Garage, from the National Science Foundation (NSF) under NSF CAREER award number 0953100; and a grant from the Defense Advanced Research Projects Agency (DARPA) Computer Science Study Group program

Any opinions, conclusions or recommendations expressed in this software and documentation are those of the authors and not necessarily reflect those of NSF or DARPA.

Comments
  • PyTorch MacOS x86 fail: section __TEXT/__const address out of range for architecture x86_64 when building NNPACK

    PyTorch MacOS x86 fail: section __TEXT/__const address out of range for architecture x86_64 when building NNPACK

    The PyTorch MacOS build with NNPack is failing with: section __TEXT/__const address out of range for architecture x86_64

    When upgrading the Xcode to latest 13.3.1, we see this behavior. The difference between Xcode 13.2.1 and 13.3 is that there are more boundary checks to prevent OOB reads.

    The conv1x1.yp.o object file has malformed load commands: $ size -mlx conv1x1.py.o Segment __TEXT: 0x36f (vmaddr 0x0 fileoff 288) Section (__TEXT, __text): 0x2ef (addr 0x0 offset 288) Section (__TEXT, __const): 0x80 (addr 0x300 offset 1088) total 0x36f total 0x36f __const section starts at 0x300, and ends at 0x380, which exceeds the __TEXT segment size (0x36f). There is manually generated object file using the third_party/NNPACK/src/x86_64-fma/blas/conv1x1.py script. Can we regenerate the object file with the latest Xcode to make sure this bug is fixed and there is no OOB access.

    opened by kulinseth 13
  • How do we debug C/C++ Application

    How do we debug C/C++ Application

    I have a question: Say I am developing an application in C/C++ and part of the code I develop in assembly, If I use peachpy to write this assembly code, How am I going to debug this assembly code?

    In visual studio while using yasm assebler this was possible. Is similar kind of thing can be done in PeachPy?

    How PeachPy is different from using intrinsics? ThankYou

    opened by kvaragan 13
  • rsp is not exposed through x86_64/__init__.py

    rsp is not exposed through x86_64/__init__.py

    I noticed that x86_64/__init__.py exposes registers from registers.py for easier access, but not rsp. Is there a specific reason for this, or just an oversight? I'll be happy to submit a fix PR if applicable

    opened by eliben 12
  • How do I use the IDIV instruction? (also: Reserving the AX register)

    How do I use the IDIV instruction? (also: Reserving the AX register)

    The IDIV instruction puts its result in the AX register. The problem I have is that I can't figure out how to prevent GeneralPurposeRegister64 from allocating AX, so my pseudoregisters end up overwriting the input and result.

    How do I prevent pseudoregisters from allocating AX?

    bug 
    opened by pwaller 12
  • Go: `uintptr` support?

    Go: `uintptr` support?

    https://golang.org/pkg/builtin/#uintptr

    It seems to be this can map directly to uintptr_t ?

    diff --git a/peachpy/x86_64/function.py b/peachpy/x86_64/function.py
    index f4614d6..00c81b9 100644
    --- a/peachpy/x86_64/function.py
    +++ b/peachpy/x86_64/function.py
    @@ -130,6 +130,8 @@ class Function:
                     return "boolean"
                 elif c_type.is_size_integer:
                     return "int" if c_type.is_signed_integer else "uint"
    +            elif c_type.is_pointer_integer:
    +                return "uintptr"
                 elif c_type.is_signed_integer:
                     return {
                         1: "int8",
    

    My rationale for wanting this is to make it easier to have slices and structs as arguments.

    A slice header ( https://golang.org/pkg/reflect/#SliceHeader ) can be simulated by having three arguments,

    s = Argument(ptr(uintptr_t))
    s_len = Argument(int64_t)
    s_cap = Argument(int64_t)
    

    (I know the documentation says to use ptrdiff_t to get Go's int, but that really makes the code confusing... In my code I'm using int64 explicitly because I know I'm on 64-bit platform.)

    However, due to the lack of mapping for uintptr, this fails when trying to generate the commented function header -- I have to put an explicit integer type for s.

    Similarly if I want to pass a pointer to a struct, using uintptr_t seems the only sane option.

    opened by dgryski 12
  • Liveness analysis does not appear to work correctly

    Liveness analysis does not appear to work correctly

    Following on from #60, consider the following simple program. It moves a value into a general purpose register and subsequently returns that value. In the meantime, it explicitly uses rax. My expectation is that the liveness analysis should determine that rax is in use and therefore the GeneralPurposeRegister64 register r should not choose rax for the allocation.

    input_ptr = Argument(ptr())
    
    with Function("foo", (input_ptr,), int64_t)  as function:
        name = LOAD.ARGUMENT(r15, input_ptr)
    
        r = GeneralPurposeRegister64()
        MOV(r, 1234)
        MOV(rax, 4567)
        MOV([r15], rax)
        RETURN(r)
    

    The resulting code I get:

    // Generated by PeachPy 0.2.0 from f.py
    
    
    // func foo(input_ptr uintptr) int64
    TEXT ·foo(SB),4,$0-16
    	MOVQ input_ptr+0(FP), R15
    	MOVQ $1234, AX
    	MOVQ $4567, AX
    	MOVQ AX, 0(R15)
    	MOVQ AX, ret+8(FP)
    	RET
    

    I have instrumented the liveness analysis code over at my instrument branch. The output of that instrumentation is as follows.

    'LOAD.ARGUMENT r15, void* input_ptr' in_mask {}; out_mask {15: 15}
    'MOV gp64-vreg<1>, 1234' in_mask {}; out_mask {-1: 15}
    'MOV rax, 4567' in_mask {}; out_mask {0: 15}
    'MOV [r15], rax' in_mask {0: 15, 15: 15}; out_mask {}
    'RETURN gp64-vreg<1>' in_mask {-1: 15}; out_mask {}
    analyze_availability -> defaultdict(<class 'int'>, {0: 15, -1: 15, 15: 15})
    Consider block [0, 5)
    analyze_liveness [0, 5) {}
    live_registers_list() masks: defaultdict(<class 'int'>, {})
    live_registers_list [0, 5) -> [defaultdict(<class 'int'>, {-1: 15}), defaultdict(<class 'int'>, {0: 15, -1: 15, 15: 15}), defaultdict(<class 'int'>, {-1: 15, 15: 15}), defaultdict(<class 'int'>, {15: 15}), defaultdict(<class 'int'>, {})]
    _analize availability: LOAD.ARGUMENT r15, void* input_ptr -> live_registers: defaultdict(<class 'int'>, {})
    _analize availability: MOV gp64-vreg<1>, 1234 -> live_registers: defaultdict(<class 'int'>, {15: 15})
    _analize availability: MOV rax, 4567 -> live_registers: defaultdict(<class 'int'>, {-1: 15, 15: 15})
    _analize availability: MOV [r15], rax -> live_registers: defaultdict(<class 'int'>, {0: 15, -1: 15, 15: 15})
    _analize availability: RETURN gp64-vreg<1> -> live_registers: defaultdict(<class 'int'>, {-1: 15})
    _analize (conflicts)  'LOAD.ARGUMENT r15, void* input_ptr' inp: set(); out: {r15}; unalloc: []; live: defaultdict(<class 'int'>, {})
    _analize (conflicts)  'MOV gp64-vreg<1>, 1234' inp: set(); out: {gp64-vreg<1>}; unalloc: []; live: defaultdict(<class 'int'>, {15: 15})
    _analize (conflicts)  'MOV rax, 4567' inp: set(); out: {rax}; unalloc: [gp64-vreg<1>]; live: defaultdict(<class 'int'>, {-1: 15, 15: 15})
        gp64-vreg<1>::conflict_internal_ids: [-1, 15]
          Conflicts for virtual 1 are now {1: {-1, 15}}
    _analize (conflicts)  'MOV [r15], rax' inp: {r15, rax}; out: set(); unalloc: []; live: defaultdict(<class 'int'>, {0: 15, -1: 15, 15: 15})
    _analize (conflicts)  'RETURN gp64-vreg<1>' inp: {gp64-vreg<1>}; out: set(); unalloc: [gp64-vreg<1>]; live: defaultdict(<class 'int'>, {-1: 15})
        gp64-vreg<1>::conflict_internal_ids: [-1]
          Conflicts for virtual 1 are now {1: {-1, 15}}
    Function._bind_registers gp64-vreg<1> to None
    Function._bind_registers gp64-vreg<1> to None
    RegisterAllocator._bind_register: Allocate virtual 1 to physical 0
    RegisterAllocator._bind_register: Considered conflicts {-1, 15}
    	LOAD.ARGUMENT r15, void* input_ptr
    	MOV rax, 1234
    	MOV rax, 4567
    	MOV [r15], rax
    	STORE.RESULT rax
    	RET
    

    I note that the list of conflicts does not change if I change the register I move 4567 into. If I do MOV(rbx, 4567) instead, I still get Conflicts for virtual 1 are now {1: {-1, 15}}. I don't quite understand the representations and intent of the register allocation code well enough to diagnose why this is, but I would expect that the conflict list depends on which register is named, but that does not seem to be the case.

    opened by pwaller 10
  • Make PeachPy pip installable

    Make PeachPy pip installable

    This patch makes setuptools a dependency. This is needed to make setup.py automatically make the Opcodes module available at setup time.

    Opcodes is made into a setup-time dependency, and if the module is installed with python setup.py build or python setup.py develop or pip install PeachPy or pip install --editable PeachPy, then the python setup.py generate command is run automatically.

    This patch depends on https://github.com/Maratyszcza/Opcodes/pull/5 because of the way setuptools handles setup-time dependencies. They are not installed proper, but made available as an .egg file. Opcodes, before Maratyszcza/Opcodes#5, tries to read the XML descriptions by opening a file relative to __file__, which is not a thing which can be read with open(). Instead, it has to use pkg_resources to do so.

    With these two PRs merged, it should be possible to pip install git+https://github.com/Maratyszcza/PeachPy. We could also then discuss making it easy to package up and upload to PyPi.

    opened by pwaller 10
  • 32 bit Python 3.5 in a 64 bit Windows 8.1 machine doesn't detect() abi correctly.

    32 bit Python 3.5 in a 64 bit Windows 8.1 machine doesn't detect() abi correctly.

    Example:

    x86_64\abi.py Line 134:

        elif osname == "Windows" and machine == "AMD64" and pointer_size == 8:
            return microsoft_x64_abi
    
    

    But when I get here on my Windows 8.1 64 bit, running Python35 (32 bit Python35 BTW.. probably should install 64 bit) it skips this abi, because my pointer_size = 4, not 8.

    ..not sure if running a 32 bit Python on a 64 bit machine is even something you want to deal with.

    I didn't mean to install 32 bit Python, and will correct in a bit - let me know if you want me to flog PeachPy in this environment a bit more before I correct and I will.

    opened by cforger 10
  • Getting

    Getting "ImportError: No module named x86_64" when running simple code

    I have this simple code:

    import peachpy
    import peachpy.x86_64
    
    x = peachpy.Argument(peachpy.int64_t)
    
    with peachpy.x86_64.Function("Add4", (x,), peachpy.int64_t) as asm_function:
        peachpy.x86_64.LOAD.ARGUMENT(peachpy.x86_64.rax, x)
        peachpy.x86_64.ADD(peachpy.x86_64.rax, 4)
        peachpy.x86_64.RETURN(peachpy.x86_64.rax)
    
    abi = peachpy.x86_64.abi.detect()
    encoded_function = asm_function.finalize(abi).encode()
    python_function = encoded_function.load()
    
    # The JIT call
    print(python_function(-100))
    

    When I run this code, I get this error:

    Traceback (most recent call last):
      File "C:/Users/Oround/Desktop/Tests.py", line 2, in <module>
        import peachpy.x86_64
    ImportError: No module named x86_64
    

    Why am I getting this error? Is there something I could do to fix it?

    opened by bifunctor 9
  • Example does not work on Linux amd64

    Example does not work on Linux amd64

    Get this error -> python -m peachpy.x86_64 -mabi=sysv -mimage-format=elf -o matmul.o matmul-opt.py /usr/bin/python: No module named avx; 'peachpy.x86_64' is a package and cannot be directly executed

    Also running make gives this -> user@ne:~/Downloads/PeachPy-master/examples/make$ make python -m peachpy.x86_64 -MMD -MF matmul-opt.d -o matmul-opt.o matmul-opt.py /usr/bin/python: No module named avx; 'peachpy.x86_64' is a package and cannot be directly executed Makefile:12: recipe for target 'matmul-opt.o' failed make: *** [matmul-opt.o] Error 1

    This is on ubuntu wily with built in Python 2.7.10.

    opened by deepankarsharma 6
  • Go-amd64: map intptr_t and uintptr_t to Go's equivalents

    Go-amd64: map intptr_t and uintptr_t to Go's equivalents

    The generator outputs an error for functions with signed/unsigned_int argument. Here's the last few lines of the error:

    File "/Library/Python/2.7/site-packages/peachpy/x86_64/function.py", line 987, in __init__
        self.go_signature = function.go_signature
      File "/Library/Python/2.7/site-packages/peachpy/x86_64/function.py", line 158, in go_signature
        go_argument_types = list(map(c_to_go_type, map(operator.attrgetter("ctype"), self.arguments)))
      File "/Library/Python/2.7/site-packages/peachpy/x86_64/function.py", line 149, in c_to_go_type
        }[ctype.size]
    KeyError: None
    

    It also outputs an error when the return type is signed/unsigned_int. Right now I'm substituting int64_t/uint64_t for signed/unsigned_int and just change the function signature to use int/uint since int and uint type in go is actually represented as 64-bit in amd64 as stated here. It would also be nice if Go's uintptr can also be supported.

    opened by robskie 6
  • Improve Windows compatibility

    Improve Windows compatibility

    Hi, this improves the Windows compatibility of PeachPy. In particular, it fixes #121. The problem was under Windows the default encoding for open() is cp1252 instead of utf-8. So by always using utf-8 for the TextWriter it is now possible to generate Go asm under Windows.

    The second commit deals with the problems described in PR #43. Under Windows it is not possible to unlink an open file. With this the writers close the file before attempting to unlink it. Just like @bawr described in his last comment but apparently never did.

    Closes #121, closes #43

    opened by ydylla 3
  • pytest tests/arm/test_arm.py is failing

    pytest tests/arm/test_arm.py is failing

    % pytest tests/arm/test_arm.py

    ================================== test session starts ==================================
    platform darwin -- Python 3.10.6, pytest-7.1.3, pluggy-1.0.0
    rootdir: /Users/cclauss/Python/itinerant_futurizer/PeachPy
    collected 1 item
    
    tests/arm/test_arm.py F                                                           [100%]
    
    ======================================= FAILURES ========================================
    ____________________________________ TestARM.runTest ____________________________________
    
    self = <tests.arm.test_arm.TestARM testMethod=runTest>
    
        def runTest(self):
    
            # Implement function void add_1(const uint32_t *src, uint32_t *dst, size_t length)
            source_arg = Argument(ptr(const_uint32_t))
            destination_arg = Argument(ptr(uint32_t))
            length_arg = Argument(size_t)
    
            # This optimized kernel will target Intel Nehalem processors. Any instructions which are not
            # supported on Intel Nehalem (e.g. AVX instructions) will generate an error. If you don't have
            # a particular target in mind, use "Unknown"
    >       with Function("add_1", (source_arg, destination_arg, length_arg), abi=ABI.GnuEABIHF, report_generation=False) as add_function:
    E       NameError: name 'ABI' is not defined
    
    tests/arm/test_arm.py:17: NameError
    ================================ short test summary info ================================
    FAILED tests/arm/test_arm.py::TestARM::runTest - NameError: name 'ABI' is not defined
    =================================== 1 failed in 0.03s ===================================
    
    opened by cclauss 1
  • GitHub Action to lint Python code

    GitHub Action to lint Python code

    Test results: https://github.com/cclauss/PeachPy/actions

    % pip install --editable . % pytest --ignore=tests/arm/test_arm.py

    ============================= test session starts ==============================
    platform linux -- Python 3.10.7, pytest-7.1.3, pluggy-1.0.0
    rootdir: /home/runner/work/PeachPy/PeachPy
    collected 1309 items
    
    tests/test_elf.py .                                                      [  0%]
    tests/test_literal.py ...........                                        [  0%]
    tests/x86_64/test_analysis.py ...                                        [  1%]
    tests/x86_64/test_function.py ........                                   [  1%]
    tests/x86_64/test_golang.py ...                                          [  1%]
    tests/x86_64/test_labels.py .......                                      [  2%]
    tests/x86_64/test_load.py .                                              [  2%]
    tests/x86_64/test_register_allocation.py ......                          [  3%]
    tests/x86_64/test_register_constraints.py ..............                 [  4%]
    tests/x86_64/test_relocation.py ............                             [  5%]
    tests/x86_64/test_return.py ...................                          [  6%]
    tests/x86_64/encoding/test_amd.py ...................................... [  9%]
    ..............................................                           [ 12%]
    tests/x86_64/encoding/test_avx.py ...................................... [ 15%]
    ........................................................................ [ 21%]
    ........................................................................ [ 26%]
    ........................................................................ [ 32%]
    ........................................................................ [ 37%]
    ........................................................................ [ 43%]
    ........................................................................ [ 48%]
    ...........................................................              [ 53%]
    tests/x86_64/encoding/test_crypto.py .......................             [ 55%]
    tests/x86_64/encoding/test_fma.py ...................................... [ 57%]
    ..........................................                               [ 61%]
    tests/x86_64/encoding/test_generic.py .................................. [ 63%]
    ........................................................................ [ 69%]
    ........................................................................ [ 74%]
    ...........................                                              [ 76%]
    tests/x86_64/encoding/test_imm.py ..                                     [ 77%]
    tests/x86_64/encoding/test_mask.py ..................................... [ 79%]
    ..............                                                           [ 80%]
    tests/x86_64/encoding/test_mmxsse.py ................................... [ 83%]
    ........................................................................ [ 89%]
    ........................................................................ [ 94%]
    .......................................................................  [100%]
    
    ============================= 1309 passed in 6.40s =============================
    
    opened by cclauss 2
  • Passing a Pointer as an argument

    Passing a Pointer as an argument

    Hi im getting the error:

    TypeError: <class 'main.LP_INPUT'> is not a C type

    if I need to pass a pointer to a struct. I have successfully defined the struct and it also works if I call the function from user32 dll. But I can not get it working with peachpy.

    Please check the attached screenshot. Would be insane if someone can figure that out.

    Best Screenshot_8 t

    opened by pain0LY 0
  • go-generate:  invalid UTF-8 encoding

    go-generate: invalid UTF-8 encoding

    After running go generate and trying to build the example using the main branch of PeachPy, I get the following error:

    .\dot_product_amd64.s:11:6: invalid UTF-8 encoding
    .\dot_product_amd64.s:11:6: invalid UTF-8 encoding
    .\dot_product_amd64.s:11: expected '(', found DotProduct
    asm: assembly of .\dot_product_amd64.s failed
    

    After some investigation, using asm code from other examples, and a hex editor, it turns out that editing TEXT ·DotProduct(SB),4,$0-28 to TEXT ·DotProduct(SB),4,$0-28 solves the issue.

    i.e.: the byte c2 seems to be missing before the function name declaration? But it doesn't show by default in an editor.

    I'm new to go ASM and I have no idea of what is going on here.

    I'm using go1.18.2 windows/amd64

    opened by Pro7ech 0
  • Why is PUSH(r32/m32) not supported?

    Why is PUSH(r32/m32) not supported?

    Error: "Invalid operand types: PUSH r32"

    From the source code:

    class PUSH(Instruction):
        """Push Value Onto the Stack"""
    
        def __init__(self, *args, **kwargs):
            """Supported forms:
    
                * PUSH(imm32)
                * PUSH(r16/m16)
                * PUSH(r64/m64)
            """
    

    Is it intended that PUSH(r32/m32) is missing? Same for POP

    opened by Ou7law007 0
Owner
Marat Dukhan
Marat Dukhan
An implementation of Python in Common Lisp

CLPython - an implementation of Python in Common Lisp CLPython is an open-source implementation of Python written in Common Lisp. With CLPython you ca

Willem Broekema 339 Jan 4, 2023
The Python programming language

This is Python version 3.10.0 alpha 5 Copyright (c) 2001-2021 Python Software Foundation. All rights reserved. See the end of this file for further co

Python 49.7k Dec 30, 2022
Grumpy is a Python to Go source code transcompiler and runtime.

Grumpy: Go running Python Overview Grumpy is a Python to Go source code transcompiler and runtime that is intended to be a near drop-in replacement fo

Google 10.6k Dec 24, 2022
DO NOT USE. Implementation of Python 3.x for .NET Framework that is built on top of the Dynamic Language Runtime.

IronPython 3 IronPython3 is NOT ready for use yet. There is still much that needs to be done to support Python 3.x. We are working on it, albeit slowl

IronLanguages 2k Dec 30, 2022
MicroPython - a lean and efficient Python implementation for microcontrollers and constrained systems

The MicroPython project This is the MicroPython project, which aims to put an implementation of Python 3.x on microcontrollers and small embedded syst

MicroPython 15.7k Dec 31, 2022
Pyjion - A JIT for Python based upon CoreCLR

Pyjion Designing a JIT API for CPython A note on development Development has moved to https://github.com/tonybaloney/Pyjion FAQ What are the goals of

Microsoft 1.6k Dec 30, 2022
A faster and highly-compatible implementation of the Python programming language. The code here is out of date, please follow our blog

Pyston is a faster and highly-compatible implementation of the Python programming language. Version 2 is currently closed source, but you can find the

null 4.9k Dec 21, 2022
The Stackless Python programming language

This is Python version 3.7.0 alpha 4+ Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 20

Stackless Python 891 Jan 3, 2023
A mini implementation of python library.

minipy author = RQDYSGN date = 2021.10.11 version = 0.2 1. 简介 基于python3.7环境,通过py原生库和leetcode上的一些习题构建的超小型py lib。 2. 环境 Python 3.7 2. 结构 ${project_name}

RQDYGSN 2 Oct 26, 2021
A faster and highly-compatible implementation of the Python programming language.

Pyston Pyston is a fork of CPython 3.8.8 with additional optimizations for performance. It is targeted at large real-world applications such as web se

null 2.3k Jan 9, 2023
Rust syntax and lexical analyzer implemented in Python.

Rust Scanner Rust syntax and lexical analyzer implemented in Python. This project was made for the Programming Languages class at ESPOL (SOFG1009). Me

Joangie Marquez 0 Jul 3, 2022
Core Python libraries ported to MicroPython

This is a repository of libraries designed to be useful for writing MicroPython applications.

MicroPython 1.8k Jan 7, 2023
Simple Assembler with python

Assembler with python converts assembly source code to machine code Requirements Python 3 ?? Usage python main.py [source] [output] [source] : Path t

Amir mohammad 1 Dec 24, 2021
A Tandy Color Computer 1, 2, and 3 assembler written in Python

CoCo Assembler and File Utility Table of Contents What is it? Requirements License Installing Assembler Assembler Usage Input File Format Print Symbol

Craig Thomas 16 Nov 3, 2022
HatAsm - a HatSploit native powerful assembler and disassembler that provides support for all common architectures

HatAsm - a HatSploit native powerful assembler and disassembler that provides support for all common architectures.

EntySec 8 Nov 9, 2022
Python 3 script unpacking statically x86 CryptOne packer.

Python 3 script unpacking statically x86 CryptOne packer. CryptOne versions: 2021/08 until now (2021/12)

null 5 Feb 23, 2022
High performance Cross-platform Inference-engine, you could run Anakin on x86-cpu,arm, nv-gpu, amd-gpu,bitmain and cambricon devices.

Anakin2.0 Welcome to the Anakin GitHub. Anakin is a cross-platform, high-performance inference engine, which is originally developed by Baidu engineer

null 514 Dec 28, 2022
An x86 old-debug-like program.

An x86 old-debug-like program.

Pablo Niklas 1 Jan 10, 2022
A topology optimization framework written in Taichi programming language, which is embedded in Python.

Taichi TopOpt (Under Active Development) Intro A topology optimization framework written in Taichi programming language, which is embedded in Python.

Li Zhehao 41 Nov 17, 2022
A Persistent Embedded Graph Database for Python

Cog - Embedded Graph Database for Python cogdb.io New release: 2.0.5! Installing Cog pip install cogdb Cog is a persistent embedded graph database im

Arun Mahendra 214 Dec 30, 2022