示例#1
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
示例#2
0
 def _as_var(self, gv):
     if gv.is_const:
         gv_var = Var(gv.type)
         #XXX provide correct cast here
         self.asm.append(' %s=%s %s %s to %s' % (
             gv_var.operand2(), inttoptr, i32, gv.operand2(), gv_var.type))
         return gv_var
     return gv
示例#3
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
示例#4
0
 def _trunc_to(self, gv_x, restype=None):
     restype = restype or gv_x.type
     if restype is gv_x.type:
         return self.genop_same_as(None, gv_x)
     gv_result = Var(restype)
     self.asm.append(' %s=%s %s to %s' % (
         gv_result.operand2(), trunc, gv_x.operand(), restype))
     return gv_result
示例#5
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
示例#6
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
示例#7
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
示例#8
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()))
示例#9
0
 def __init__(self, rgenop, label, inputargtypes):
     self.rgenop = rgenop
     self.label = label
     self.inputargs = [Var(type) for type in inputargtypes]
     self.phinodes = {}   # dict {source block: [source vars]}
     self.asm = []
     rgenop.blocklist.append(self)
示例#10
0
 def _cast_to(self, gv_x, restype=None):
     t = gv_x.type
     restype = restype or t
     if restype is t:
         return self.genop_same_as(None, gv_x)
     gv_result = Var(restype)
     if restype[-1] == '*':
         if gv_x.is_const:
             cst = inttoptr
             t = i32
         else:
             cst = bitcast
     else:
         cst = zext
     self.asm.append(' %s=%s %s %s to %s ;2' % (
         gv_result.operand2(), cst, t, gv_x.operand2(), restype))
     return gv_result
示例#11
0
 def genop_same_as(self, kind, gv_x): #XXX why do we need a 'kind' here?
     if gv_x.is_const:    # must always return a var
         restype = gv_x.type
         gv_result = Var(restype)
         v = gv_x.operand2()
         if restype[-1] == '*':
             cst = inttoptr
             t   = i32
             if v == 'null':
                 v = '0'
         else:
             cst = bitcast
             t   = restype
         self.asm.append(' %s=%s %s %s to %s ;1' % (
             gv_result.operand2(), cst, t, v, restype))
         return gv_result
     else:
         return gv_x
示例#12
0
 def op_int_rshift(self, gv_x, gv_y):
     gv_y_i8 = Var(i8)
     self.asm.append(' %s=%s %s to %s' % (
         gv_y_i8.operand2(), trunc, gv_y.operand(), i8))
     gv_result = Var(gv_x.type)
     self.asm.append(' %s=%sshr %s,%s' % (
         gv_result.operand2(), shr_prefix[gv_x.signed], gv_x.operand(), gv_y_i8.operand()))
     return gv_result
示例#13
0
 def op_int_lshift(self, gv_x, gv_y):
     gv_y_i8 = Var(i8)
     self.asm.append(' %s=%s %s to %s' % (
         gv_y_i8.operand2(), trunc, gv_y.operand(), i8))
     gv_result = Var(gv_x.type)
     self.asm.append(' %s=shl %s,%s' % (
         gv_result.operand2(), gv_x.operand(), gv_y_i8.operand()))
     return gv_result
示例#14
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()))
示例#15
0
    def genop_getarrayitem(self, arraytoken, gv_ptr, gv_index):
        array_length_offset, array_items_offset, item_size, item_type = arraytoken
        log('%s Builder.genop_getarrayitem %s,%s[%s]' % (
            self.block.label, arraytoken, gv_ptr.operand(), gv_index.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()))

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

        return gv_result
示例#16
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
示例#17
0
    def _itemaddr(self, arraytoken, gv_index):
        length_offset, items_offset, item_size, item_type = arraytoken

        gv_size2 = Var(i32) #i386 uses self.itemaddr here
        self.asm.append(' %s=mul %s,%d' % (
            gv_size2.operand2(), gv_index.operand(), item_size))

        gv_size3 = Var(i32)
        self.asm.append(' %s=add %s,%d' % (
            gv_size3.operand2(), gv_size2.operand(), items_offset))

        return gv_size3
示例#18
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
示例#19
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
示例#20
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
示例#21
0
 def __init__(self, sigtoken, name):
     self.name = name
     self.sigtoken = sigtoken
     argtypes, restype = sigtoken
     self.inputargs = [Var(type) for type in argtypes]
示例#22
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
示例#23
0
 def _abs(self, gv_x, nullstr='0'):
     gv_comp    = Var(i1)
     gv_abs_pos = Var(gv_x.type)
     gv_result  = Var(gv_x.type)
     if nullstr == 'null' or nullstr == '0':
         cmp = scmp
     else:
         cmp = fcmp
     self.asm.append(' %s=%sge %s,%s' % (
         gv_comp.operand2(), cmp, gv_x.operand(), nullstr))
     self.asm.append(' %s=sub %s %s,%s' % (
         gv_abs_pos.operand2(), gv_x.type, nullstr, gv_x.operand2()))
     self.asm.append(' %s=select %s,%s,%s' % (
         gv_result.operand2(), gv_comp.operand(), gv_x.operand(), gv_abs_pos.operand()))
     return gv_result
示例#24
0
 def op_bool_not(self, gv_x):
     gv_result = Var(i1)
     self.asm.append(' %s=select %s,%s false,%s true' % (
         gv_result.operand2(), gv_x.operand(), i1, i1))
     return gv_result