Ejemplo n.º 1
0
 def codegen(context, builder, signature, args):
     data, idx, ch = args
     if bitsize < 32:
         ch = builder.trunc(ch, IntType(bitsize))
     ptr = builder.bitcast(data, IntType(bitsize).as_pointer())
     builder.store(ch, builder.gep(ptr, [idx]))
     return context.get_dummy_value()
Ejemplo n.º 2
0
    def visit_Writeln(self, node: Writeln) -> None:
        """Converts the contents of the command writeln to LLVM ir code and adds the
        print call to the operating system.

        Args:
            node (Writeln): content passed in the command writeln
        """

        self.printf_counter += 1
        output_operation_type = "%s"

        if isinstance(node.content[0], BinaryOperator):
            self._create_instruct("BinaryOperator", is_printf=True)

        writeln_content = self.visit(node.content[0])

        if isinstance(writeln_content, VarSymbol):
            content = self.GLOBAL_MEMORY[writeln_content.name]
        else:
            content = writeln_content

        content_type = type(content.type).__name__

        if self.builder.block.is_terminated:
            self._create_instruct(typ=content_type, is_printf=True)

        if isinstance(content.type, DoubleType):
            output_operation_type = "%f"

        output_format = f"{output_operation_type}\n\0"
        printf_format = Constant(
            ArrayType(IntType(8), len(output_format)),
            bytearray(output_format.encode("utf8")),
        )

        fstr = GlobalVariable(self.module,
                              printf_format.type,
                              name=f"fstr_{self.printf_counter}")
        fstr.linkage = "internal"
        fstr.global_constant = True
        fstr.initializer = printf_format

        writeln_type = FunctionType(IntType(32), [], var_arg=True)
        writeln = Function(
            self.module,
            writeln_type,
            name=f"printf_{content_type}_{self.printf_counter}",
        )

        body = self.builder.alloca(content.type)
        temp_loaded = self.builder.load(body)
        self.builder.store(temp_loaded, body)

        void_pointer_type = IntType(8).as_pointer()
        casted_arg = self.builder.bitcast(fstr, void_pointer_type)
        self.builder.call(writeln, [casted_arg, body])
        self.builder.ret_void()
Ejemplo n.º 3
0
    def visit_Boolean(self, node: Boolean) -> Constant:
        """Converts the boolean type to an integer (i1) constant.

        Args:
            nodo (Boolean): a token represeting a literal boolean type

        Returns:
            Constant: a constant of type IntType (1) representing the Boolean type:
                1 = True and 0 = False
        """

        if node.token.type == TokenType.FALSE:
            return Constant(IntType(1), 0)
        else:
            return Constant(IntType(1), 1)
Ejemplo n.º 4
0
 def emit_IF(self):
     then_block = self.function.append_basic_block()
     else_block = self.function.append_basic_block()
     exit_block = self.function.append_basic_block()
     self.builder.cbranch(self.builder.trunc(self.pop(), IntType(1)), then_block, else_block)
     self.set_block(then_block)
     self.blocks.append([then_block, else_block, exit_block])
Ejemplo n.º 5
0
def test_array_repr():
    int8 = IntType(8)
    tp = ArrayType(int8, 3)
    int8_1 = Constant(int8, 1)
    tp1 = tp.gep(int8_1)
    print(tp1, type(tp1))
    values = [Constant(int8, x) for x in (5, 10, -15)]
    c = Constant(tp, values)
    print(c)
    assert str(c) == "[3 x i8] [i8 5, i8 10, i8 -15]"
    c = Constant(tp, bytearray(b"\x01\x02\x03"))
    print(c)
    assert str(c) == '[3 x i8] c"\\01\\02\\03"'
Ejemplo n.º 6
0
    def visit_String(self, node: String) -> Constant:
        """Converts the literal string to an array of characters.

        Args:
            node (String): a token represeting a string (literal)

        Returns:
            Constant: a constant containing a array of characters
        """

        content = node.value
        return Constant(ArrayType(IntType(8), len(content)),
                        bytearray(content.encode("utf8")))
Ejemplo n.º 7
0
    def _create_instruct(self, typ: str, is_printf: bool = False) -> None:
        """Create a new Function instruction and attach it to a new Basic Block Entry.

        Args:
            typ (str): node type.
            is_printf (bool, optional): Defaults to False.
        """

        if is_printf or typ in ["String", "ArrayType"]:
            self.str_counter += 1
            self.func_name = f"_{typ}.{self.str_counter}"
            func_type = FunctionType(VoidType(), [])
        elif typ == "Boolean":
            self.bool_counter += 1
            self.func_name = f"_{typ}.{self.bool_counter}"
            func_type = FunctionType(IntType(1), [])
        else:
            self.expr_counter += 1
            self.func_name = f"_{typ}_Expr.{self.expr_counter}"
            func_type = FunctionType(DoubleType(), [])

        main_func = Function(self.module, func_type, self.func_name)
        bb_entry = main_func.append_basic_block("entry")
        self.builder = IRBuilder(bb_entry)
Ejemplo n.º 8
0
'''
from collections import ChainMap
from functools import partialmethod

# LLVM imports. Don't change this.

from llvmlite.ir import (Module, IRBuilder, Function, IntType, DoubleType,
                         VoidType, Constant, GlobalVariable, FunctionType)

# Declare the LLVM type objects that you want to use for the low-level
# in our intermediate code.  Basically, you're going to need to
# declare the integer, float, and char types here.  These correspond
# to the types being used the intermediate code being created by
# the ircode.py file.

int_type = IntType(32)  # 32-bit integer
float_type = DoubleType()  # 64-bit float
byte_type = IntType(8)  # 8-bit integer

void_type = VoidType()  # Void type.  This is a special type
# used for internal functions returning
# no value

LLVM_TYPE_MAPPING = {
    'I': int_type,
    'F': float_type,
    'B': byte_type,
    None: void_type
}

# The following class is going to generate the LLVM instruction stream.
Ejemplo n.º 9
0
 def emit_CBRANCH(self, test, true_label, false_label):
     true_block = self.basicblocks[true_label]
     false_block = self.basicblocks[false_label]
     self.builder.cbranch(self.builder.trunc(self.temps[test], IntType(1)),
                          true_block, false_block)
Ejemplo n.º 10
0
#     func f(a int, b int) int {
#          var c int;
#          if a < b {
#               c = a + b;
#          } else {
#               c = a - b;
#          }
#          return c;
#     }
#

from llvmlite.ir import (Module, IRBuilder, IntType, Function, FunctionType)

mod = Module('example')
f_func = Function(mod,
                  FunctionType(IntType(32),
                               [IntType(32), IntType(32)]),
                  name='f')

block = f_func.append_basic_block("entry")
builder = IRBuilder(block)

# Get the arguments
a_var, b_var = f_func.args

# Allocate the result variable
c_var = builder.alloca(IntType(32), name='c')

# Perform the comparison
testvar = builder.icmp_signed('<', a_var, b_var)
Ejemplo n.º 11
0
 def emit_ALLOCI(self, name):
     var = self.builder.alloca(IntType(32), name=name)
     self.builder.store(Constant(int_type, 0), var)
     self.vars[name] = var
Ejemplo n.º 12
0
import math
import sys
import unittest

from llvmlite.ir import (
    Constant,
    FloatType,
    DoubleType,
    LiteralStructType,
    IntType,
    ArrayType,
    HalfType,
)
from llvmlite.tests import TestCase

int8 = IntType(8)
int16 = IntType(16)

PY36_OR_LATER = sys.version_info[:2] >= (3, 6)


class TestValueRepr(TestCase):
    def test_double_repr(self):
        def check_repr(val, expected):
            c = Constant(DoubleType(), val)
            self.assertEqual(str(c), expected)

        check_repr(math.pi, "double 0x400921fb54442d18")
        check_repr(float("inf"), "double 0x7ff0000000000000")
        check_repr(float("-inf"), "double 0xfff0000000000000")
Ejemplo n.º 13
0
from collections import ChainMap

# LLVM imports. Don't change this.

from llvmlite.ir import (
    Module, IRBuilder, Function, IntType, DoubleType, VoidType, Constant, GlobalVariable,
    FunctionType
    )

# Declare the LLVM type objects that you want to use for the low-level
# in our intermediate code.  Basically, you're going to need to
# declare the integer, float, and char types here.  These correspond
# to the types being used the intermediate code being created by
# the ircode.py file.

int_type    = IntType(32)         # 32-bit integer
float_type  = DoubleType()        # 64-bit float
void_type   = VoidType()          # Void type.  This is a special type
                                  # used for internal functions returning
                                  # no value

# Mapping of Wabbit names to LLVM types
typemap = {
    'int': int_type,
    'float' : float_type,
    'char': int_type,
    'bool': int_type,
    None: void_type
}

# The following class is going to generate the LLVM instruction stream.  
Ejemplo n.º 14
0
 def cast_to_byte(self, value):
     return self.builder.trunc(value, IntType(1))
Ejemplo n.º 15
0
 def emit_CBRANCH(self, test_target, true_label, false_label):
     true_block = self.get_block(true_label)
     false_block = self.get_block(false_label)
     testvar = self.temps[test_target]
     self.builder.cbranch(self.builder.trunc(testvar, IntType(1)),
                          true_block, false_block)
Ejemplo n.º 16
0
 def emit_CBREAK(self):
     next_block = self.function.append_basic_block()
     self.builder.cbranch(self.builder.trunc(self.pop(), IntType(1)), self.blocks[-1][1], next_block)
     self.set_block(next_block)
Ejemplo n.º 17
0
# A sample of executing an integer < in LLVM

from llvmlite.ir import (Module, Function, FunctionType, IntType, IRBuilder)

mod = Module('example')

# Define a function:
#
#    func lessthan(x int, y int) bool {
#         return x < y;
#    }
#
# Note: The result of boolean operations is a 1-bit integer

func = Function(mod,
                FunctionType(IntType(1),
                             [IntType(32), IntType(32)]),
                name='lessthan')

block = func.append_basic_block("entry")
builder = IRBuilder(block)

# The icmp_signed() instruction is used for all comparisons on
# integers.  For floating point, use fcmp_ordered().  The compare operation
# takes an operator expressed as a string such as '<', '>', '==',
# etc.

result = builder.icmp_signed('<', func.args[0], func.args[1])
builder.ret(result)

# ---- Test Code
Ejemplo n.º 18
0
# llvmgen.py

code = [('VARI', 'x'), ('CONSTI', 4), ('STORE', 'x'), ('VARI', 'y'),
        ('CONSTI', 5), ('STORE', 'y'), ('VARI', 'd'), ('LOAD', 'x'),
        ('LOAD', 'x'), ('MULI', ), ('LOAD', 'y'), ('LOAD', 'y'), ('MULI', ),
        ('ADDI', ), ('STORE', 'd'), ('LOAD', 'd'), ('PRINTI', )]

from llvmlite.ir import (Module, Function, FunctionType, IntType, VoidType,
                         Constant, IRBuilder)

int_type = IntType(32)
void_type = VoidType()


class LLVMGenerator:
    def __init__(self):
        self.module = Module('hello')
        self._print_int = Function(self.module,
                                   FunctionType(void_type, [int_type]),
                                   name='_print_int')

        self.function = Function(self.module,
                                 FunctionType(int_type, []),
                                 name='main')
        self.block = self.function.append_basic_block('entry')
        self.builder = IRBuilder(self.block)

        self.stack = []
        self.vars = {}

    def emit(self, code):
Ejemplo n.º 19
0
 def codegen(context, builder, signature, args):
     data, idx = args
     ptr = builder.bitcast(data, IntType(bitsize).as_pointer())
     ch = builder.load(builder.gep(ptr, [idx]))
     return builder.zext(ch, IntType(32))
Ejemplo n.º 20
0
 def emit_CBRANCH(self, test, label1, label2):
     tmp = self.builder.trunc(self.temps[test], IntType(1), 'tmp')
     self.builder.cbranch(tmp, self.blocks[label1], self.blocks[label2])
Ejemplo n.º 21
0
# hello_llvm.py
from llvmlite.ir import (Module, Function, FunctionType, IntType, IRBuilder,
                         Constant)

mod = Module('hello')
int_type = IntType(32)
hello_func = Function(mod, FunctionType(int_type, []), name='hello')
block = hello_func.append_basic_block('entry')
builder = IRBuilder(block)
builder.ret(Constant(IntType(32), 37))
print(mod)
Ejemplo n.º 22
0
# hellollvm.py

from llvmlite.ir import (Module, Function, FunctionType, IntType, Constant,
                         IRBuilder)
from llvmlite.ir import DoubleType

mod = Module('hello')

hello_func = Function(mod, FunctionType(IntType(32), []), name='hello')
block = hello_func.append_basic_block('entry')
builder = IRBuilder(block)
builder.ret(Constant(IntType(32), 37))

ty_double = DoubleType()
dsquared_func = Function(mod,
                         FunctionType(ty_double, [ty_double, ty_double]),
                         name='dsquared')
block = dsquared_func.append_basic_block('entry')
builder = IRBuilder(block)

# Get the function args
x, y = dsquared_func.args

# Compute temporary values for x*x and y*y
xsquared = builder.fmul(x, x)
ysquared = builder.fmul(y, y)

# Sum the values and return the result
d2 = builder.fadd(xsquared, ysquared)
builder.ret(d2)
Ejemplo n.º 23
0
# hellollvm.py

from llvmlite.ir import (
    Module, Function, FunctionType, IntType,
    Constant, IRBuilder
    )

mod = Module('hello')
hello_func = Function(mod, 
                      FunctionType(IntType(32), []), 
                      name='hello')
block = hello_func.append_basic_block('entry')
builder = IRBuilder(block)
builder.ret(Constant(IntType(32), 37))

# A user-defined function
from llvmlite.ir import DoubleType

ty_double = DoubleType()
dsquared_func = Function(mod, 
                         FunctionType(ty_double, [ty_double, ty_double]), 
                         name='dsquared')
block = dsquared_func.append_basic_block('entry')
builder = IRBuilder(block)

# Get the function args
x, y = dsquared_func.args

# Compute temporary values for x*x and y*y
xsquared = builder.fmul(x, x)
ysquared = builder.fmul(y, y)
Ejemplo n.º 24
0
#               total = total + n;
#               n = n - 1;
#          }
#          return total;
#     }
#

from llvmlite.ir import (
    Module, IRBuilder, IntType, Function, FunctionType, Constant
    )

mod = Module('example')

# Declare the f function with our loop
f_func = Function(mod,
                  FunctionType(IntType(32), [IntType(32)]),
                  name='f')

block = f_func.append_basic_block("entry")
builder = IRBuilder(block)

# Copy the argument to a local variable.  For reasons, that are 
# complicated, we copy the function argument to a local variable
# allocated on the stack (this makes mutations of the variable
# easier when looping).

n_var = builder.alloca(IntType(32), name='n')
builder.store(f_func.args[0], n_var)

# Allocate the result variable
total_var = builder.alloca(IntType(32), name='total')