def visit_Cmp(self, e): f = self.IRB.icmp_signed if e.is_signed else self.IRB.icmp_unsigned cmp_op = { EX.ExprCmp.OpEq: '==', EX.ExprCmp.OpNeq: '!=', EX.ExprCmp.OpLt: '<', EX.ExprCmp.OpLte: '<=', EX.ExprCmp.OpGt: '>', EX.ExprCmp.OpGte: '>=' } return f(cmp_op[e.op], EX.visit(e.X, self), EX.visit(e.Y, self))
def visit_Concat(self, e): # Generate a suite of OR + shifts # TODO: pass that lowers concat arg0 = e.args[0] ret = EX.visit(arg0, self) type_ = IntType(e.nbits) ret = self.IRB.zext(ret, type_) cur_bits = arg0.nbits for a in e.args[1:]: cur_arg = self.IRB.zext(EX.visit(a, self), type_) ret = self.IRB.or_( ret, self.IRB.shl(cur_arg, ll.Constant(type_, cur_bits))) cur_bits += a.nbits return ret
def visit_Broadcast(self, e): # TODO: pass that lowers broadcast # left-shift to get the idx as the MSB, and them use an arithmetic # right shift of nbits-1 type_ = IntType(e.nbits) ret = EX.visit(e.arg, self) ret = self.IRB.zext(ret, type_) ret = self.IRB.shl(ret, ll.Constant(type_, e.nbits - e.idx - 1)) return self.IRB.ashr(ret, ll.Constant(type_, e.nbits - 1))
def visit_Slice(self, e): # TODO: pass that lowers slice ret = EX.visit(e.arg, self) idxes = e.idxes # Support only sorted indxes for now if idxes != list(range(idxes[0], idxes[-1]+1)): raise ValueError("slice indexes must be continuous and sorted") if idxes[0] != 0: ret = self.IRB.lshr(ret, ll.Constant(IntType(e.arg.nbits), idxes[0])) return self.IRB.trunc(ret, IntType(len(idxes)))
def visit_Cond(self, e): cond = EX.visit(e.cond, self) bb_name = self.IRB.basic_block.name ifb = self.IRB.append_basic_block(bb_name + ".if") elseb = self.IRB.append_basic_block(bb_name + ".else") endb = self.IRB.append_basic_block(bb_name + ".endif") self.IRB.cbranch(cond, ifb, elseb) self.IRB.position_at_end(ifb) ifv = EX.visit(e.a, self) self.IRB.branch(endb) self.IRB.position_at_end(elseb) elsev = EX.visit(e.b, self) self.IRB.branch(endb) self.IRB.position_at_end(endb) ret = self.IRB.phi(IntType(e.nbits)) ret.add_incoming(ifv, ifb) ret.add_incoming(elsev, elseb) return ret
def to_llvm_ir(exprs, sym_to_value, IRB): if not llvmlite_available: raise RuntimeError("llvmlite module unavailable! can't assemble to LLVM IR...") if not isinstance(exprs, collections.Iterable): exprs = (exprs,) ret = None visitor = ToLLVMIr(sym_to_value, IRB) for e in exprs: e = lower_rol_ror(e) ret = EX.visit(e, visitor) return ret
def f(e): P = cls() return EX.visit(e, P)
def visit(self, e): return EX.visit(e, self)
def visit_nary_args(self, e, op): return op(*(EX.visit(a, self) for a in e.args))
def visit_SX(self, e): return self.IRB.sext(EX.visit(e.arg, self), IntType(e.n))
def visit_Not(self, e): return self.IRB.not_(EX.visit(e.arg, self))
def visit_value(self, e): return EX.visit(e, self)[0]