Example #1
0
 def add_case(self, gv_case):
     targetbuilder = self.builder._fork()
     self.cases.append('%s,label %%%s' % (gv_case.operand(), targetbuilder.nextlabel))
     log('%s FlexSwitch.add_case %s => %s' % (
         self.builder.block.label, gv_case.operand(), targetbuilder.nextlabel))
     targetbuilder.start_writing()
     return targetbuilder
Example #2
0
    def genop_malloc_varsize(self, varsizealloctoken, gv_size):
        log('%s Builder.genop_malloc_varsize %s,%s' % (
            self.block.label, varsizealloctoken, gv_size.operand()))

        length_offset, items_offset, item_size, item_type = varsizealloctoken

        gv_gc_malloc_fnaddr = Var('%s (%s)*' % (pi8, i32))
        #or use addGlobalFunctionMapping in libllvmjit.restart()
        self.asm.append(' %s=%s %s %d to %s ;gc_malloc_fnaddr (varsize)' % (
            gv_gc_malloc_fnaddr.operand2(), inttoptr, i32,
            gc_malloc_fnaddr(), gv_gc_malloc_fnaddr.type))

        op_size = self._itemaddr(varsizealloctoken, gv_size)

        gv_result = Var(pi8)
        self.asm.append(' %s=call %s(%s)' % (
            gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), op_size.operand()))

        gv_p = Var(gv_result.type)
        self.asm.append(' %s=getelementptr %s,%s %s' % (
            gv_p.operand2(), gv_result.operand(), i32, length_offset))

        gv_p2 = self._cast_to(gv_p, pi32) #warning: length field hardcoded as int here
        self.asm.append(' store %s, %s' % (gv_size.operand(), gv_p2.operand()))

        return gv_result
Example #3
0
 def pause_writing(self, args_gv):
     log('%s Builder.pause_writing' % self.block.label)
     assert self.asm is not None
     self.nextlabel = count.newlabel()   # for the next block
     self.asm.append(' br label %%%s' % (self.nextlabel,))
     self.asm = None
     return self
Example #4
0
 def genop_call(self, sigtoken, gv_fnptr, args_gv):
     log('%s Builder.genop_call %s,%s,%s' % (
         self.block.label, sigtoken, gv_fnptr, [v.operand() for v in args_gv]))
     argtypes, restype = sigtoken
     if isinstance(gv_fnptr, AddrConst):
         gv_fn = Var(self._funcsig_type(args_gv, restype) + '*')
         self.asm.append(' %s=%s %s %s to %s' % (
             gv_fn.operand2(), inttoptr, i32, gv_fnptr.operand2(), gv_fn.type))
         funcsig = gv_fn.operand()
     else:
         try:
             funcsig = self.rgenop.funcsig[gv_fnptr.get_integer_value()]
         except KeyError:
             funcsig = 'TODO: funcsig here'
             py.test.skip('call an address directly not supported yet')
     args_gv2 = []
     for v in args_gv:
         if v.is_const and v.type[-1] == '*': #or use some kind of 'inline' cast (see LangRef)
             t = Var(v.type)
             self.asm.append(' %s=%s %s %s to %s' % (
                 t.operand2(), inttoptr, i32, v.operand2(), v.type))
             v = t
         args_gv2.append(v)
     gv_returnvar = Var(restype)
     self.asm.append(' %s=call %s(%s)' % (
                     gv_returnvar.operand2(),
                     funcsig,
                     ','.join([v.operand() for v in args_gv2])))
     return gv_returnvar
Example #5
0
 def _add_default(self):
     targetbuilder = self.builder._fork()
     self.default_label = targetbuilder.nextlabel
     log('%s FlexSwitch.add_default => %s' % (
         self.builder.block.label, targetbuilder.nextlabel))
     targetbuilder.start_writing()
     return targetbuilder
Example #6
0
 def jump_if_true(self, gv_condition, args_for_jump_gv):
     log('%s Builder.jump_if_true %s' % (self.block.label, gv_condition.operand()))
     targetbuilder = self._fork()
     self.nextlabel = count.newlabel()
     self.asm.append(' br %s,label %%%s,label %%%s' % (
         gv_condition.operand(), targetbuilder.nextlabel, self.nextlabel))
     self.start_writing()
     return targetbuilder
Example #7
0
 def _rgenop1_generic(self, llvm_opcode, gv_x, restype=None):
     log('%s Builder._rgenop1_generic %s %s' % (
         self.block.label, llvm_opcode, gv_x.operand()))
     restype = restype or gv_x.type
     gv_result = Var(restype)
     self.asm.append(' %s=%s %s' % (
         gv_result.operand2(), llvm_opcode, gv_x.operand()))
     return gv_resulgv_comp.operand(), t
Example #8
0
 def _rgenop2_generic(self, llvm_opcode, gv_arg1, gv_arg2, restype=None):
     log('%s Builder._rgenop2_generic %s %s,%s' % (
         self.block.label, llvm_opcode, gv_arg1.operand(), gv_arg2.operand2()))
     restype = restype or gv_arg1.type
     gv_result = Var(restype)
     self.asm.append(' %s=%s %s,%s' % (
         gv_result.operand2(), llvm_opcode, gv_arg1.operand(), gv_arg2.operand2()))
     return gv_result
Example #9
0
 def finish_and_goto(self, outputargs_gv, target):
     # 'target' is a label, which for the llvm backend is a Block
     log('%s Builder.finish_and_goto' % self.block.label)
     gv = [v.operand() for v in outputargs_gv]
     log('%s Builder.finish_and_goto %s,%s' % (
         self.block.label, gv, target.label))
     self.asm.append(' br label %%%s' % (target.label,))
     target.add_incoming_link(self.block, outputargs_gv)
     self._close()
Example #10
0
 def genop_getsubstruct(self, fieldtoken, gv_ptr):
     offset, fieldtype = fieldtoken
     log('%s Builder.genop_getsubstruct (%d,%s) %s' % (
         self.block.label, offset, fieldtype, gv_ptr.operand()))
     gv_ptr_var = self._as_var(gv_ptr)
     gv_sub = Var(gv_ptr.type)
     self.asm.append(' %s=getelementptr %s,%s %d' % (
         gv_sub.operand2(), gv_ptr_var.operand(), i32, offset))
     return gv_sub
Example #11
0
 def _is_true(self, gv_x, nullstr='0'):
     log('%s Builder._is_true %s' % (self.block.label, gv_x.operand()))
     gv_result = Var(i1)
     if nullstr == 'null' or nullstr == '0':
         cmp = icmp
     else:
         cmp = fcmp
     self.asm.append(' %s=%sne %s,%s' % (
         gv_result.operand2(), cmp, gv_x.operand(), nullstr))
     return gv_result
Example #12
0
 def start_writing(self):
     log('%s Builder.start_writing' % self.nextlabel)
     assert self.nextlabel is not None
     coming_from = self.block
     # prepare the next block
     nextblock = BasicBlock(self.rgenop, self.nextlabel, [])
     self.block     = nextblock
     self.asm       = nextblock.asm
     self.nextlabel = None
     nextblock.add_incoming_link(coming_from, [])
Example #13
0
    def __init__(self, rgenop, builder, gv_exitswitch):
        log('%s FlexSwitch.__init__ %s' % (builder.block.label, gv_exitswitch.operand()))
        self.rgenop = rgenop
        self.builder = builder
        self.gv_exitswitch = gv_exitswitch

        self.default_label = None
        self.cases = []

        self.rgenop.blocklist.append(self)
Example #14
0
 def genop_setfield(self, fieldtoken, gv_ptr, gv_value):
     offset, fieldtype = fieldtoken
     log('%s Builder.genop_setfield (%d,%s) %s=%s' % (
         self.block.label, offset, fieldtype, gv_ptr.operand(), gv_value.operand()))
     gv_ptr_var = self._as_var(gv_ptr)
     gv_p = Var(gv_ptr.type)
     self.asm.append(' %s=getelementptr %s,%s %s' % (
         gv_p.operand2(), gv_ptr_var.operand(), i32, offset))
     gv_p2 = self._cast_to(gv_p, fieldtype + '*')
     self.asm.append(' store %s,%s' % (
         gv_value.operand(), gv_p2.operand()))
Example #15
0
 def genop_malloc_fixedsize(self, size):
     log('%s Builder.genop_malloc_fixedsize %s' % (
         self.block.label, str(size)))
     gv_gc_malloc_fnaddr = Var('%s (%s)*' % (pi8, i32))
     gv_result = Var(pi8)
     #or use addGlobalFunctionMapping in libllvmjit.restart()
     self.asm.append(' %s=%s %s %d to %s ;gc_malloc_fnaddr' % (
         gv_gc_malloc_fnaddr.operand2(), inttoptr, i32,
         gc_malloc_fnaddr(), gv_gc_malloc_fnaddr.type))
     self.asm.append(' %s=call %s(%s %d)' % (
         gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), i32, size))
     return gv_result
Example #16
0
 def genop_getfield(self, fieldtoken, gv_ptr):
     offset, fieldtype = fieldtoken
     log('%s Builder.genop_getfield (%d,%s) %s' % (
         self.block.label, offset, fieldtype, gv_ptr.operand()))
     gv_ptr_var = self._as_var(gv_ptr)
     gv_p = Var(gv_ptr.type)
     self.asm.append(' %s=getelementptr %s,%s %s' % (
         gv_p.operand2(), gv_ptr_var.operand(), i32, offset))
     gv_p2 = self._cast_to(gv_p, fieldtype + '*')
     gv_result = Var(fieldtype)
     self.asm.append(' %s=load %s' % (
         gv_result.operand2(), gv_p2.operand()))
     return gv_result
Example #17
0
    def genop_getarraysize(self, arraytoken, gv_ptr):
        log('%s Builder.genop_getarraysize %s,%s' % (
            self.block.label, arraytoken, gv_ptr.operand()))

        array_length_offset, array_items_offset, item_size, item_type = arraytoken
        gv_ptr_var = self._as_var(gv_ptr)

        gv_p = Var(gv_ptr_var.type)
        self.asm.append(' %s=getelementptr %s,%s %s' % (
            gv_p.operand2(), gv_ptr_var.operand(), i32, array_length_offset))

        gv_p2 = self._cast_to(gv_p, pi32)

        gv_result = Var(i32)
        self.asm.append(' %s=load %s' % (
            gv_result.operand2(), gv_p2.operand()))

        return gv_result
Example #18
0
    def genop_setarrayitem(self, arraytoken, gv_ptr, gv_index, gv_value):
        array_length_offset, array_items_offset, item_size, item_type = arraytoken
        log('%s Builder.genop_setarrayitem %s,%s[%s]=%s' % (
            self.block.label, arraytoken, gv_ptr.operand(), gv_index.operand(), gv_value.operand()))

        gv_ptr_var = self._as_var(gv_ptr)

        gv_p = Var(gv_ptr_var.type)
        self.asm.append(' %s=getelementptr %s,%s %s' % (
            gv_p.operand2(), gv_ptr_var.operand(), i32, array_items_offset))

        gv_p2 = self._cast_to(gv_p, item_type + '*')

        gv_p3 = Var(gv_p2.type)
        self.asm.append(' %s=getelementptr %s,%s' % (
            gv_p3.operand2(), gv_p2.operand(), gv_index.operand()))

        self.asm.append(' store %s,%s' % (
            gv_value.operand(), gv_p3.operand()))
Example #19
0
    def newgraph(self, sigtoken, name):
        if name in self.funcused:
            self.funcused[name] += 1
            name = '%s_%d' % (name, self.funcused[name])
        else:
            self.funcused[name] = 0

        log('   RLLVMGenOp.newgraph %s,%s' % (sigtoken, name))

        prologueblock = PrologueBlock(sigtoken, name)
        self.blocklist = [prologueblock]
        builder = Builder(self, coming_from=prologueblock)
        prologueblock.startblocklabel = builder.nextlabel

        argtypes, restype = sigtoken
        n = len(self.funcsig) * 2 + 1     #+1 so we recognize these pre compilation 'pointers'
        self.name = name
        self.funcsig[n] = '%s %s%s' % (restype, globalprefix, name)
        self.gv_entrypoint = IntConst(n)    #note: updated by Builder.end() (i.e after compilation)
        args = list(prologueblock.inputargs)
        return builder, self.gv_entrypoint, args
Example #20
0
    def enter_next_block(self, kinds, args_gv):
        assert self.nextlabel is None
        coming_from = self.block
        newlabel = count.newlabel()
        # we still need to properly terminate the current block
        # (with a br to go to the next block)
        # see: http://llvm.org/docs/LangRef.html#terminators
        self.asm.append(' br label %%%s' % (newlabel,))
        # prepare the next block
        nextblock = BasicBlock(self.rgenop, newlabel, kinds)
        log('%s Builder enter block %s' % (
            nextblock.label, [v.operand() for v in nextblock.inputargs]))
        self.block = nextblock
        self.asm   = nextblock.asm

        # link the two blocks together and update args_gv
        nextblock.add_incoming_link(coming_from, args_gv)
        for i in range(len(args_gv)):
            args_gv[i] = nextblock.inputargs[i]

        return self.block
Example #21
0
    def genop_getarraysubstruct(self, arraytoken, gv_ptr, gv_index):
        '''
        self.mc.MOV(edx, gv_ptr.operand(self))
        op = self.itemaddr(edx, arraytoken, gv_index)
        self.mc.LEA(eax, op)
        return self.returnvar(eax)
        '''
        #XXX WIP
        log('%s Builder.genop_getarraysubstruct %s,%s,%s' % (
            self.block.label, arraytoken, gv_ptr.operand(), gv_index.operand()))

        array_length_offset, array_items_offset, item_size, item_type = arraytoken

        op_size = self._itemaddr(arraytoken, gv_index)

        gv_ptr_var = self._as_var(gv_ptr)

        gv_result = Var(pi8)
        self.asm.append(' %s=getelementptr %s,%s' % (
            gv_result.operand2(), gv_ptr_var.operand(), op_size.operand()))

        return gv_result
Example #22
0
    def end(self):
        log('   RLLVMGenOp.end')
        self.blocklist.append(EpilogueBlock())
        asmlines = []
        for block in self.blocklist:
            block.writecode(asmlines)
        if LINENO:
            asmlines = ['%s ;%d' % (asmlines[i], i+1) for i in range(len(asmlines))]
        asm_string = '\n'.join(asmlines)

        self.blocklist = None
        if PRINT_SOURCE:
            print asm_string
        logger.dump(asm_string)
        parse_ok = llvmjit.parse(asm_string)
        if not parse_ok:
            raise ParseException()
        llvmjit.transform(3) #optimize module (should be on functions actually)
        function   = llvmjit.getNamedFunction(self.name)
        entrypoint = llvmjit.getPointerToFunctionAsInt(function)
        # XXX or directly cast the ctypes ptr to int with:
        #   ctypes.cast(ptr, c_void_p).value
        self.funcsig[entrypoint] = self.funcsig[self.gv_entrypoint.value]
        self.gv_entrypoint.value = entrypoint
Example #23
0
 def flexswitch(self, gv_exitswitch, args_gv):
     log('%s Builder.flexswitch %s' % (self.block.label, gv_exitswitch.operand()))
     flexswitch = FlexSwitch(self.rgenop, self, gv_exitswitch)
     return flexswitch, flexswitch._add_default()
Example #24
0
 def _fork(self):
     targetbuilder = Builder(self.rgenop, coming_from=self.block)
     log('%s Builder._fork => %s' % (self.block.label, targetbuilder.nextlabel))
     return targetbuilder
Example #25
0
 def finish_and_return(self, sigtoken, gv_returnvar):
     log('%s Builder.finish_and_return %s,%s' % (
         self.block.label, sigtoken, gv_returnvar.operand()))
     self.asm.append(' ret ' + gv_returnvar.operand())
     self._close()
Example #26
0
 def genop1(self, opname, gv_arg):
     log('%s Builder.genop1 %s %s' % (
         self.block.label, opname, gv_arg.operand()))
     genmethod = getattr(self, 'op_' + opname)
     return genmethod(gv_arg)
Example #27
0
 def genop2(self, opname, gv_arg1, gv_arg2):
     log('%s Builder.genop2 %s %s,%s' % (
         self.block.label, opname, gv_arg1.operand(), gv_arg2.operand()))
     genmethod = getattr(self, 'op_' + opname)
     return genmethod(gv_arg1, gv_arg2)