Compare commits

...
Sign in to create a new pull request.

2 commits

Author SHA1 Message Date
Siu Kwan Lam
0dc22f26a0 Begin to add C-ABI ArgInfo 2013-10-05 16:17:44 +08:00
Siu Kwan Lam
da55b76202 Add buildscript for devel branch 2013-10-05 14:03:13 +08:00
6 changed files with 289 additions and 0 deletions

View file

@ -0,0 +1,6 @@
set LLVMPY_DYNLINK=0
set INCLUDE=%LIBRARY_INC%
set LIBPATH=%LIBRARY_LIB%
set LIB=%LIBRARY_LIB%
%PYTHON% setup.py install
if errorlevel 1 exit 1

View file

@ -0,0 +1,13 @@
#!/bin/bash
if [[ (`uname` == Linux) && (`uname -m` != armv6l) ]]
then
export CC=gcc
#gcc44
export CXX=g++
#g++44
fi
export LLVMPY_DYNLINK=$DISTRO_BUILD
$PYTHON setup.py install

View file

@ -0,0 +1,28 @@
package:
name: llvmpy
version: 99.9.9
source:
git_url: git@github.com:llvmpy/llvmpy.git
git_tag: devel
requirements:
build:
- llvm
- python
#- chrpath [linux]
run:
- llvm [unix]
- python
test:
imports:
- llvm
- llvmpy
- llvmpy._api
- llvmpy._capsule
- llpython
- llvm_array
- llvm_cbuilder

View file

@ -0,0 +1,19 @@
import sys
import platform
import llvm
from llvm.core import Module
from llvm.ee import EngineBuilder
m = Module.new('fjoidajfa')
eb = EngineBuilder.new(m)
target = eb.select_target()
print('target.triple=%r' % target.triple)
if sys.platform == 'darwin':
s = {'64bit': 'x86_64', '32bit': 'x86'}[platform.architecture()[0]]
assert target.triple.startswith(s + '-apple-darwin')
assert llvm.test(verbosity=2) == 0
print('llvm.__version__: %s' % llvm.__version__)
#assert llvm.__version__ == '0.12.0'

195
llvm/abi.py Normal file
View file

@ -0,0 +1,195 @@
'''
Provide C ABI information
Reference to
- http://clang.llvm.org/doxygen/classclang_1_1ABIArgInfo.html
- http://clang.llvm.org/doxygen/CodeGen_2TargetInfo_8cpp_source.html
See X86_32ABIInfo, computeInfo, classifyArgumentType
'''
from collections import namedtuple
import llvm.core as lc
AGGREGATE_TYPES = frozenset([lc.TYPE_STRUCT, lc.TYPE_ARRAY])
class ABIArgInfo(object):
'''
ABI argument info
Try to be a close translation of clang::ABIArgInfo.
(See http://clang.llvm.org/doxygen/classclang_1_1ABIArgInfo.html)
But, this is for C not C++.
'''
__slots__ = ['_kind', '_typedata', '_paddingtype', '_uintdata',
'_booldata0', '_booldata1', '_inreg', '_paddinginreg']
# Enum for argument info kind
DIRECT = 0
EXTEND = 1
IGNORE = 2
INDIRECT = 3
EXPAND = 4
def __init__(self, kind, td=None, ui=0, b0=False, b1=False, ir=False,
pir=False, p=None):
self._kind = kind
self._typedata = td
self._paddingtype = p
self._uintdata = ui
self._booldata0 = b0
self._booldata1 = b1
self._inreg = ir
self._paddinginreg = pir
def __repr__(self):
data = []
if self.is_direct:
data.append('Direct')
data.append('coerce=%s' % self.coerce_to_type)
elif self.is_indirect:
data.append('Indirect')
data.append('align=%s' % self.indirect_align)
data.append('byval=%s' % self.indirect_by_val)
data.append('realign=%s' % self.indirect_by_realign)
elif self.is_extend:
data.append('Extend')
elif self.is_ignore:
data.append('Ignore')
elif self.is_expand:
data.append('Expand')
else:
raise AssertionError('invalid kind: %s' % self._kind)
return '<ArgInfo %s>' % ' '.join(data)
# ---- accessors ----
@property
def is_direct(self):
return self._kind == self.DIRECT
@property
def is_indirect(self):
return self._kind == self.INDIRECT
@property
def is_extend(self):
return self._kind == self.EXTEND
@property
def is_ignore(self):
return self._kind == self.IGNORE
@property
def is_expand(self):
return self._kind == self.EXPAND
@property
def can_have_coerce_to_type(self):
return self.is_direct or self.is_extend
@property
def direct_offset(self):
assert self.is_direct or self.is_extend
return self._uintdata
@property
def padding_type(self):
return self._paddingtype
@property
def padding_in_reg(self):
return self._paddinginreg
@property
def coerce_to_type(self):
assert self.can_have_coerce_to_type
return self._typedata
@coerce_to_type.setter
def coerce_to_type(self, ty):
self._typedata = ty
@property
def in_reg(self):
return self.is_direct() or self.is_extend or self.is_indirect
@property
def indirect_align(self):
assert self.is_indirect
return self._uintdata
@property
def indirect_by_val(self):
assert self.is_indirect
return self._booldata0
@property
def indirect_by_realign(self):
assert self.is_indirect
return self._booldata1
# ---- factories ----
@classmethod
def get_ignore(cls):
return cls(kind=cls.IGNORE)
@classmethod
def get_extend(cls, ty=None):
return cls(kind=cls.EXTEND, td=ty)
@classmethod
def get_direct(cls):
return cls(kind=cls.DIRECT)
class ABIInfo(object):
def __init__(self, datalayout):
self.datalayout = datalayout
def compute_info(self, return_type, args):
self.return_info = self.classify_return_type(return_type)
self.arg_infos = []
for a in args:
info = self.classify_argument_type(a)
self.arg_infos.append(info)
def classify_return_type(self, retty):
raise NotImplementedError
def classify_argument_type(self, argty):
raise NotImplementedError
class DefaultABIInfo(ABIInfo):
def classify_argument_type(self, argty):
if argty.kind in AGGREGATE_TYPES:
return ABIArgInfo.get_indirect()
if self.promotable_integers(argty):
return ABIArgInfo.get_extend()
else:
return ABIArgInfo.get_direct()
def classify_return_type(self, retty):
if retty.kind == lc.TYPE_VOID:
return ABIArgInfo.get_ignore()
if retty.kind in AGGREGATE_TYPES:
return ABIArgInfo.get_indirect()
if self.promotable_integers(retty):
return ABIArgInfo.get_extend()
else:
return ABIArgInfo.get_direct()
def promotable_integers(self, ty):
if ty.kind != lc.TYPE_INTEGER:
return False
abisize = self.datalayout.abi_size(ty) * 8
return ty.width < abisize
#------------------------------------------------------------------------------
# X86-32
#------------------------------------------------------------------------------
class X86_32ABIInfo(ABIInfo):
MIN_ABI_STACK_ALIGN = 4 # bytes

28
llvm/tests/test_abi.py Normal file
View file

@ -0,0 +1,28 @@
from __future__ import print_function
import unittest
from llvm.core import Type
from llvm.ee import TargetMachine
from llvm.abi import DefaultABIInfo
from .support import TestCase, tests
class TestDefaultABIArgInfo(TestCase):
'''Simply exercise the API
'''
def test_abi_int(self):
tm = TargetMachine.new()
td = tm.target_data.clone()
abiinfo = DefaultABIInfo(td)
abiinfo.compute_info(Type.void(), [Type.int(1), Type.int(8),
Type.int(16), Type.int(32),
Type.int(64)])
print(abiinfo.arg_infos)
print(abiinfo.return_info)
abiinfo.compute_info(Type.int(32), [])
print(abiinfo.arg_infos)
print(abiinfo.return_info)
tests.append(TestDefaultABIArgInfo)
if __name__ == '__main__':
unittest.main()