Пример #1
0
def EmitCall(fun: ir.Fun, bbl: ir.Bbl, call_ins: ir.Ins, op_stack, mem_base,
             callee: ir.Fun):
    """
    if the wasm function has the signature:
    [a b] -> [c d]
    This means the top of op_stack must be [a b] before the call and will be [c d] after the call

    The called Cwerg function expects the right most input to be pushed on the stack first, so we get
    pusharg b
    pusharg a
    We always pass mem_base as the the first argument so there is also
    pusharg mem_base

    The called Cwerg function pushes the results also from right to left
    [callee] pusharg d
    [callee] pusharg c


    """
    # print (f"########## calling {callee.name} in:{callee.input_types}  out:{callee.output_types}")
    # print ("# STACK")
    # print (op_stack)
    for dk in reversed(callee.input_types[1:]):
        arg = op_stack.pop(-1)
        assert arg.kind == dk, f"expected type {dk} [{arg}] got {arg.kind}"
        bbl.AddIns(ir.Ins(o.PUSHARG, [arg]))
    bbl.AddIns(ir.Ins(o.PUSHARG, [mem_base]))

    bbl.AddIns(call_ins)

    for dk in callee.output_types:
        dst = GetOpReg(fun, dk, len(op_stack))
        op_stack.append(dst)
        bbl.AddIns(ir.Ins(o.POPARG, [dst]))
Пример #2
0
def HandleRotl(dst: ir.Reg, op1: ir.Reg, op2: ir.Reg, bbl: ir.Bbl):
    assert dst != op1
    assert dst.kind is o.DK.U32 or dst.kind is o.DK.U64, f"{dst}"
    bitwidth = ir.Const(dst.kind, dst.kind.bitwidth())
    bbl.AddIns(ir.Ins(o.SHL, [dst, op1, op2]))
    bbl.AddIns(ir.Ins(o.SUB, [op2, bitwidth, op2]))
    bbl.AddIns(ir.Ins(
        o.SHR, [op1, op1, op2]))  # here the unsigned requirement kicks in
    bbl.AddIns(ir.Ins(o.OR, [dst, dst, op1]))
Пример #3
0
 def FinalizeResultsCopy(self, op_stack, bbl: ir.Bbl, fun: ir.Fun):
     # print (f"@@ FinalizeCopy {fun.name}:  {self.num_results}")
     dst_pos = self.stack_start + len(self.result_types)
     src_pos = len(op_stack)
     for i in range(len(self.result_types)):
         dst_pos -= 1
         src_pos -= 1
         op = op_stack[src_pos]
         dst_reg = GetOpReg(fun, op.kind, dst_pos)
         if dst_reg != op:
             bbl.AddIns(ir.Ins(o.MOV, [dst_reg, op]))
Пример #4
0
def HandleMax(dst: ir.Reg, op1: ir.Reg, op2: ir.Reg, bbl: ir.Bbl):
    bbl.AddIns(ir.Ins(o.CMPLT, [dst, op2, op1, op1, op2]))