def emitabs(self, node): if (len(node.args) != 1): raise PyllvmError("mmath: one argument to abs") ty = self.codeGen.typer.inferType(node.args[0]) v = self.codeGen.visit(node.args[0]) if (ty == int): return self.codeGen.builder.call(self.codeGen._mabs, [v]) elif (ty == float): return self.codeGen.builder.call(self.codeGen._fmabs, [v]) raise PyllvmError("mmath: unhandled type for abs")
def emitfloat(self, node): if (len(node.args) != 1): raise PyllvmError("mmath: one argument to float") ty = self.codeGen.typer.inferType(node.args[0]) v = self.codeGen.visit(node.args[0]) if (ty == float): return v elif (ty == int): return self.codeGen.builder.sitofp(v, llFloatType) raise PyllvmError("mmath: unhandled type for float")
def emitexp(self, node): if (len(node.args) != 1): raise PyllvmError("mmath: one argument to log") ty = self.codeGen.typer.inferType(node.args[0]) v = self.codeGen.visit(node.args[0]) if (ty == int): l = self.codeGen.builder.sitofp(v, llFloatType) return self.codeGen.builder.fptosi( self.codeGen.builder.call(self.codeGen._exp, [l]), llIntType) elif (ty == float): return self.codeGen.builder.call(self.codeGen._exp, [v]) raise PyllvmError("mmath: unhandled type for log")
def emitsqrt(self, node): if (len(node.args) != 1): raise PyllvmError("mmath: one argument to sqrt") ty = self.codeGen.typer.inferType(node.args[0]) v = self.codeGen.visit(node.args[0]) if (ty == int): # first cast int to float, then do float sqrt i2f = self.codeGen.builder.sitofp(v, llFloatType, 'i2f') ret = self.codeGen.builder.call(self.codeGen._fsqrt, [i2f]) return self.codeGen.builder.fptosi(ret, llIntType) elif (ty == float): return self.codeGen.builder.call(self.codeGen._fsqrt, [v]) raise PyllvmError("mmath: unhandled type for sqrt")
def emitmod(self, node): if (len(node.args) != 2): raise PyllvmError("mmath: 2 arguments needed for mod") lty = self.codeGen.typer.inferType(node.args[0]) rty = self.codeGen.typer.inferType(node.args[1]) if lty != rty: raise PyllvmError("mmath: both arguments must match type for mod") l = self.codeGen.visit(node.args[0]) r = self.codeGen.visit(node.args[1]) if (rty == int): return self.codeGen.builder.srem(l, r) elif (rty == float): return self.codeGen.builder.frem(l, r) raise PyllvmError("mmath: unhandled type for mod")
def genUniqueSymbol(self, type): """ Generate unique symbol. """ nMax = 1000 baseName = "tmp" done = False i = 0 while 1: name = baseName + str(self.genNum) if self.find(name) == None: newSym = Symbol(name, type, "variable") self.append(newSym) return newSym self.genNum += 1 i += 1 if i > nMax: raise PyllvmError("Symbol Table: Can't define unique symbol.")
def __div__(self, b): if not isinstance(b, vec): raise PyllvmError("MUDA: RHS is not a type of vec") tmp = vec([x / y for x, y in zip(self.value, b.value)]) return tmp
def emitzeros(self, node): # get start and end points ty = self.codeGen.typer.inferType(node.args[0]) if (ty != int and ty != float): raise PyllvmError("mmath: zeros needs numerical arguments") for n in node.args: if not isinstance(n, compiler.ast.Const): raise PyllvmError("mmath: need to pass zeros constant values") if len(node.args) == 1: start = 0 end = int(node.args[0].value) z = 0 else: start = 0 end = int(node.args[0].value) z = node.args[1].value ty = self.codeGen.typer.inferType(node.args[1]) if (end < start): raise PyllvmError("mmath: bad zeros args") # malloc array if (ty == int): arrTy = llvm.core.Type.array(llIntType, end - start) else: arrTy = llvm.core.Type.array(llFloatType, end - start) m_ptr = self.codeGen.builder.alloca_array( arrTy, llvm.core.Constant.int(llIntType, end - start)) # copy all the values from the stack one into the heap zero = llvm.core.Constant.int(llIntType, 0) count = 0 for v in range(start, end + 1): index = llvm.core.Constant.int(llIntType, count) # create value to store if ty == int: val = llvm.core.Constant.int(llIntType, z) else: val = llvm.core.Constant.real(llFloatType, z) # store values in malloc'd array m = self.codeGen.builder.gep(m_ptr, [zero, index]) self.codeGen.builder.store(val, m) count = count + 1 # reset expr to the malloc'd array ptr return m_ptr
def emitpow(self, node): if (len(node.args) != 2): raise PyllvmError("mmath: 2 arguments needed for pow") lty = self.codeGen.typer.inferType(node.args[0]) rty = self.codeGen.typer.inferType(node.args[1]) l = self.codeGen.visit(node.args[0]) r = self.codeGen.visit(node.args[1]) if rty == int: r = self.codeGen.builder.sitofp(r, llFloatType) elif rty != float: raise PyllvmError("mmath: exponent must be numerical") if (lty == int): l = self.codeGen.builder.sitofp(l, llFloatType) return self.codeGen.builder.fptosi( self.codeGen.builder.call(self.codeGen._fpow, [l, r]), llIntType) elif (lty == float): return self.codeGen.builder.call(self.codeGen._fpow, [l, r]) raise PyllvmError("mmath: base for exponent must be numerical")
def lookup(self, name): """ Find a symbol with name. If a symbol was not found, raise a exeption. """ for i in range(len(self.symbols)): d = self.symbols[i][1] if d.has_key(name): return d[name] raise PyllvmError("Symbol Table: Undefine symbol: ", name)
def __init__(self, *args): v = [] if len(args) == 4: # vec(1.0, 2.0, 3.0, 4.0) for a in args: assert isinstance( a, float), ("Arg must be a float type, but %s(%s) is given" % (a, type(a))) v.append(a) elif len(args) == 1: if isinstance(args[0], list): # vec([1.0, 2.0, 3.0, 4.0]) v = args[0] elif isinstance(args[0], float): # vec(1.0) v.append(args[0]) v.append(args[0]) v.append(args[0]) v.append(args[0]) else: raise PyllvmError("MUDA: Unsupported input for vec():", args) elif len(args) == 0: # vec() v = [0.0, 0.0, 0.0, 0.0] else: raise PyllvmError("MUDA: Unsupported input for vec():", args) self.value = v
def __le__(self, b): if not isinstance(b, vec): raise PyllvmError("MUDA: RHS is not a type of vec") r = [0.0, 0.0, 0.0, 0.0] for i in range(4): if self.value[i] <= b.value[i]: r[i] = b2f(0xffffffff) else: r[i] = b2f(0x00000000) return vec(r)
def __getattr__(self, name): # # Handle swizzle # d = {'x': 0, 'y': 1, 'z': 2, 'w': 3} assert len(name) < 5, "Invalid attribute: %s" % name if len(name) == 1: return self.value[d[name]] v = vec([0.0, 0.0, 0.0, 0.0]) for (i, s) in enumerate(name): if not d.has_key(s): raise PyllvmError("MUDA: Invalid letter for swizzle:", name) v.value[i] = self.value[d[s]] for i in range(len(name), 4): v.value[i] = self.value[d[name[-1]]] return v