forked from M-Labs/artiq
compiler/ir: introduce Fraction type (incomplete)
This commit is contained in:
parent
0832507c26
commit
76cef042a5
@ -107,6 +107,13 @@ class Visitor:
|
||||
fn = node.func.id
|
||||
if fn in ast_unfuns:
|
||||
return ast_unfuns[fn](self.visit_expression(node.args[0]), self.builder)
|
||||
elif fn == "Fraction":
|
||||
r = ir_values.VFraction()
|
||||
if self.builder is not None:
|
||||
numerator = self.visit_expression(node.args[0])
|
||||
denominator = self.visit_expression(node.args[1])
|
||||
r.set_value_nd(self.builder, numerator, denominator)
|
||||
return r
|
||||
elif fn == "syscall":
|
||||
return self.env.syscall(node.args[0].s,
|
||||
[self.visit_expression(expr) for expr in node.args[1:]],
|
||||
|
@ -186,6 +186,92 @@ class VBool(VInt):
|
||||
r.set_ssa_value(builder, self.get_ssa_value(builder))
|
||||
return r
|
||||
|
||||
# Fraction type
|
||||
|
||||
class VFraction(_Value):
|
||||
def get_llvm_type(self):
|
||||
return lc.Type.vector(lc.Type.int(64), 2)
|
||||
|
||||
def __repr__(self):
|
||||
return "<VFraction>"
|
||||
|
||||
def same_type(self, other):
|
||||
return isinstance(other, VFraction)
|
||||
|
||||
def merge(self, other):
|
||||
if not isinstance(other, VFraction):
|
||||
raise TypeError
|
||||
|
||||
def _simplify(self, builder):
|
||||
pass # TODO
|
||||
|
||||
def set_value_nd(self, builder, numerator, denominator):
|
||||
numerator = numerator.o_int64(builder).get_ssa_value(builder)
|
||||
denominator = denominator.o_int64(builder).get_ssa_value(builder)
|
||||
value = lc.Constant.undef(lc.Type.vector(lc.Type.int(64), 2))
|
||||
value = builder.insert_element(value, numerator, lc.Constant.int(lc.Type.int(), 0))
|
||||
value = builder.insert_element(value, denominator, lc.Constant.int(lc.Type.int(), 1))
|
||||
self.set_ssa_value(builder, value)
|
||||
self._simplify(builder)
|
||||
|
||||
def set_value(self, builder, n):
|
||||
if not isinstance(n, VFraction):
|
||||
raise TypeError
|
||||
self.set_ssa_value(builder, n.get_ssa_value(builder))
|
||||
|
||||
def o_bool(self, builder):
|
||||
r = VBool()
|
||||
if builder is not None:
|
||||
zero = lc.Constant.int(lc.Type.int(64), 0)
|
||||
numerator = builder.extract_element(self.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), 0))
|
||||
r.set_ssa_value(builder, builder.icmp(lc.ICMP_NE, numerator, zero))
|
||||
return r
|
||||
|
||||
def o_intx(self, target_bits, builder):
|
||||
if builder is None:
|
||||
return VInt(target_bits)
|
||||
else:
|
||||
r = VInt(64)
|
||||
numerator = builder.extract_element(self.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), 0))
|
||||
denominator = builder.extract_element(self.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), 1))
|
||||
r.set_ssa_value(builder, builder.sdiv(numerator, denominator))
|
||||
return r.o_intx(target_bits, builder)
|
||||
|
||||
def o_roundx(self, target_bits, builder):
|
||||
if builder is None:
|
||||
return VInt(target_bits)
|
||||
else:
|
||||
r = VInt(64)
|
||||
numerator = builder.extract_element(self.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), 0))
|
||||
denominator = builder.extract_element(self.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), 1))
|
||||
h_denominator = builder.ashr(denominator, lc.Constant.int(lc.Type.int(), 1))
|
||||
r_numerator = builder.add(numerator, h_denominator)
|
||||
r.set_ssa_value(builder, builder.sdiv(r_numerator, denominator))
|
||||
return r.o_intx(target_bits, builder)
|
||||
|
||||
def _o_eq_inv(self, other, builder, invert):
|
||||
if isinstance(other, VFraction):
|
||||
r = VBool()
|
||||
if builder is not None:
|
||||
ee = []
|
||||
for i in range(2):
|
||||
es = builder.extract_element(self.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), i))
|
||||
eo = builder.extract_element(other.get_ssa_value(builder), lc.Constant.int(lc.Type.int(), i))
|
||||
ee.append(builder.icmp(lc.ICMP_EQ, es, eo))
|
||||
ssa_r = builder.and_(ee[0], ee[1])
|
||||
if invert:
|
||||
ssa_r = builder.xor(ssa_r, lc.Constant.int(lc.Type.int(1), 1))
|
||||
r.set_ssa_value(builder, ssa_r)
|
||||
return r
|
||||
else:
|
||||
return NotImplemented
|
||||
|
||||
def o_eq(self, other, builder):
|
||||
return self._o_eq_inv(other, builder, False)
|
||||
|
||||
def o_ne(self, other, builder):
|
||||
return self._o_eq_inv(other, builder, True)
|
||||
|
||||
# Operators
|
||||
|
||||
def _make_unary_operator(op_name):
|
||||
|
Loading…
Reference in New Issue
Block a user