Add initial vector support
This commit is contained in:
parent
562e3c1e46
commit
5319fb8c98
3 changed files with 74 additions and 8 deletions
76
builder.py
76
builder.py
|
|
@ -26,6 +26,14 @@ def _is_real(ty):
|
||||||
lc.Type.ppc_fp128() ]
|
lc.Type.ppc_fp128() ]
|
||||||
return any(ty == x for x in tys)
|
return any(ty == x for x in tys)
|
||||||
|
|
||||||
|
def _is_vector(ty, of=None):
|
||||||
|
if isinstance(ty, lc.VectorType):
|
||||||
|
if of is not None:
|
||||||
|
return of(ty.element)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def _is_pointer(ty):
|
def _is_pointer(ty):
|
||||||
return isinstance(ty, lc.PointerType)
|
return isinstance(ty, lc.PointerType)
|
||||||
|
|
||||||
|
|
@ -42,6 +50,11 @@ def _is_cstruct(ty):
|
||||||
def _list_values(iterable):
|
def _list_values(iterable):
|
||||||
return [i.value for i in iterable]
|
return [i.value for i in iterable]
|
||||||
|
|
||||||
|
def _auto_coerce_index(cbldr, idx):
|
||||||
|
if not isinstance(idx, CValue):
|
||||||
|
idx = cbldr.constant(types.int, idx)
|
||||||
|
return idx
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
def _change_block_temporarily(builder, bb):
|
def _change_block_temporarily(builder, bb):
|
||||||
origbb = builder.basic_block
|
origbb = builder.basic_block
|
||||||
|
|
@ -892,11 +905,11 @@ class CValue(object):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_int(self):
|
def is_int(self):
|
||||||
return _is_int(self.type)
|
return _is_int(self.type) or _is_vector(self.type, _is_int)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_real(self):
|
def is_real(self):
|
||||||
return _is_real(self.type)
|
return _is_real(self.type) or _is_vector(self.type, _is_real)
|
||||||
|
|
||||||
def cast(self, ty, unsigned=False):
|
def cast(self, ty, unsigned=False):
|
||||||
'''cast to another type
|
'''cast to another type
|
||||||
|
|
@ -984,6 +997,10 @@ class CValue(object):
|
||||||
return self._cmp_op('ge')(rhs)
|
return self._cmp_op('ge')(rhs)
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_vector(self):
|
||||||
|
return _is_vector(self.type)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_pointer(self):
|
def is_pointer(self):
|
||||||
return _is_pointer(self.type)
|
return _is_pointer(self.type)
|
||||||
|
|
@ -992,17 +1009,41 @@ class CValue(object):
|
||||||
if not self.is_pointer:
|
if not self.is_pointer:
|
||||||
raise TypeError("Must be a pointer; got %s" % self.type)
|
raise TypeError("Must be a pointer; got %s" % self.type)
|
||||||
|
|
||||||
|
def _ensure_is_vector(self):
|
||||||
|
if not self.is_vector:
|
||||||
|
raise TypeError("Must be a vector; got %s" % self.type)
|
||||||
|
|
||||||
def __getitem__(self, idx):
|
def __getitem__(self, idx):
|
||||||
'''implement access indexing
|
'''implement access indexing
|
||||||
|
|
||||||
Uses GEP.
|
Uses GEP.
|
||||||
'''
|
'''
|
||||||
self._ensure_is_pointer()
|
|
||||||
if not isinstance(idx, CValue):
|
|
||||||
idx = self.parent.constant(types.int, idx)
|
|
||||||
bldr = self.parent.builder
|
bldr = self.parent.builder
|
||||||
ptr = bldr.gep(self.value, [idx.value])
|
if self.is_pointer:
|
||||||
return CVar(self.parent, ptr)
|
if type(idx) is slice:
|
||||||
|
# just handle case by case
|
||||||
|
# Case #1: A[idx:] get poointer offset by idx
|
||||||
|
if not idx.step and not idx.stop:
|
||||||
|
idx = _auto_coerce_index(self.parent, idx.start)
|
||||||
|
ptr = bldr.gep(self.value, [idx.value])
|
||||||
|
return CArray(self.parent, ptr)
|
||||||
|
else: # return an variable at idx
|
||||||
|
idx = _auto_coerce_index(self.parent, idx)
|
||||||
|
ptr = bldr.gep(self.value, [idx.value])
|
||||||
|
return CVar(self.parent, ptr)
|
||||||
|
elif self.is_vector:
|
||||||
|
idx = _auto_coerce_index(self.parent, idx)
|
||||||
|
val = bldr.extract_element(self.value, idx.value)
|
||||||
|
return CTemp(self.parent, val)
|
||||||
|
else:
|
||||||
|
raise TypeError("Must be a pointer or vector; got %s" % self.type)
|
||||||
|
|
||||||
|
def __setitem__(self, idx, val):
|
||||||
|
self._ensure_is_vector()
|
||||||
|
idx = _auto_coerce_index(self.parent, idx)
|
||||||
|
bldr = self.parent.builder
|
||||||
|
vec = bldr.insert_element(self.value, val.value, idx.value)
|
||||||
|
bldr.store(vec, self.ptr)
|
||||||
|
|
||||||
def load(self, volatile=False):
|
def load(self, volatile=False):
|
||||||
'''memory load for pointer types
|
'''memory load for pointer types
|
||||||
|
|
@ -1181,6 +1222,7 @@ class CVar(CValue):
|
||||||
else:
|
else:
|
||||||
return cstruct_class(self.parent, self.ptr)
|
return cstruct_class(self.parent, self.ptr)
|
||||||
|
|
||||||
|
|
||||||
class CArray(CValue):
|
class CArray(CValue):
|
||||||
'''wraps a array
|
'''wraps a array
|
||||||
|
|
||||||
|
|
@ -1201,6 +1243,26 @@ class CArray(CValue):
|
||||||
def type(self):
|
def type(self):
|
||||||
return self.base_ptr.type
|
return self.base_ptr.type
|
||||||
|
|
||||||
|
def vector_load(self, count):
|
||||||
|
parent = self.parent
|
||||||
|
values = [self[i] for i in range(count)]
|
||||||
|
vec = parent.constant_null(types.vector(self.type.pointee, count)).value
|
||||||
|
for i, v in enumerate(values):
|
||||||
|
i = parent.constant(types.int, i)
|
||||||
|
vec = parent.builder.insert_element(vec, v.value, i.value)
|
||||||
|
return CTemp(parent, vec)
|
||||||
|
|
||||||
|
def vector_store(self, vec):
|
||||||
|
if vec.type.element != self.type.pointee:
|
||||||
|
raise TypeError("Type mismatch; expect %s but got %s" % \
|
||||||
|
(vec.type.element, self.type.pointee))
|
||||||
|
parent = self.parent
|
||||||
|
for i in range(vec.type.count):
|
||||||
|
i = parent.constant(types.int, i)
|
||||||
|
val = parent.builder.extract_element(vec.value, i.value)
|
||||||
|
self[i].assign(CTemp(parent, val))
|
||||||
|
return self
|
||||||
|
|
||||||
class CStruct(CValue):
|
class CStruct(CValue):
|
||||||
'''Wraps a structure
|
'''Wraps a structure
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ class CExecutor(object):
|
||||||
else:
|
else:
|
||||||
retty = typeinfo[0]
|
retty = typeinfo[0]
|
||||||
argtys = typeinfo[1:]
|
argtys = typeinfo[1:]
|
||||||
|
|
||||||
prototype = ct.CFUNCTYPE(retty, *argtys)
|
prototype = ct.CFUNCTYPE(retty, *argtys)
|
||||||
fnptr = self.engine.get_pointer_to_function(fn)
|
fnptr = self.engine.get_pointer_to_function(fn)
|
||||||
return prototype(fnptr)
|
return prototype(fnptr)
|
||||||
|
|
|
||||||
|
|
@ -28,3 +28,8 @@ pointer_size = _determine_pointer_size()
|
||||||
|
|
||||||
intp = {32: int32, 64: int64}[pointer_size]
|
intp = {32: int32, 64: int64}[pointer_size]
|
||||||
|
|
||||||
|
|
||||||
|
# vector
|
||||||
|
def vector(ty, ct):
|
||||||
|
return Type.vector(ty, 4)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue