Exemplo n.º 1
0
 def test_reordering(self):
     s8 = frame_pos(8, INT)
     s12 = frame_pos(12, INT)
     s20 = frame_pos(19, INT)
     s24 = frame_pos(1, INT)
     remap_frame_layout(self.assembler, [r7, s8, s20, r4], [s8, r4, r7, r2], "?")
     assert self.assembler.got([("mov", r4, r2), ("mov", s8, r4), ("mov", r7, s8), ("mov", s20, r7)])
Exemplo n.º 2
0
 def test_cycle_2(self):
     s8 = frame_pos(8, INT)
     s12 = frame_pos(12, INT)
     s20 = frame_pos(19, INT)
     s24 = frame_pos(1, INT)
     s2 = frame_pos(2, INT)
     s3 = frame_pos(3, INT)
     remap_frame_layout(
         self.assembler, [r0, s8, r1, s20, r0, s20, s24, r3, s2, s3], [s8, s20, r1, r0, r4, s24, r5, s12, s3, s2], ip
     )
     assert self.assembler.got(
         [
             ("mov", r0, r4),
             ("mov", s24, r5),
             ("mov", r3, s12),
             ("mov", s20, ip),
             ("mov", ip, s24),
             ("push", s8),
             ("mov", r0, s8),
             ("mov", s20, r0),
             ("pop", s20),
             ("push", s3),
             ("mov", s2, ip),
             ("mov", ip, s3),
             ("pop", s2),
         ]
     )
Exemplo n.º 3
0
 def test_simple_framelocs(self):
     s8 = frame_pos(0, INT)
     s12 = frame_pos(13, INT)
     s20 = frame_pos(20, INT)
     s24 = frame_pos(221, INT)
     remap_frame_layout(self.assembler, [s8, r7, s12], [s20, s24, r9], ip)
     assert self.assembler.ops == [("mov", s8, ip), ("mov", ip, s20), ("mov", r7, s24), ("mov", s12, r9)]
Exemplo n.º 4
0
 def test_cycle(self):
     s8 = frame_pos(8, INT)
     s12 = frame_pos(12, INT)
     s20 = frame_pos(19, INT)
     s24 = frame_pos(1, INT)
     remap_frame_layout(self.assembler, [r4, s8, s20, r7], [s8, r7, r4, s20], "?")
     assert self.assembler.got([("push", s8), ("mov", r4, s8), ("mov", s20, r4), ("mov", r7, s20), ("pop", r7)])
Exemplo n.º 5
0
 def test_simple_framelocs(self):
     s8 = frame_pos(0, INT)
     s12 = frame_pos(13, INT)
     s20 = frame_pos(20, INT)
     s24 = frame_pos(221, INT)
     remap_frame_layout(self.assembler, [s8, r7, s12], [s20, s24, r9], ip)
     assert self.assembler.ops == [('mov', s8, ip), ('mov', ip, s20),
                                   ('mov', r7, s24), ('mov', s12, r9)]
Exemplo n.º 6
0
 def test_reordering(self):
     s8 = frame_pos(8, INT)
     s12 = frame_pos(12, INT)
     s20 = frame_pos(19, INT)
     s24 = frame_pos(1, INT)
     remap_frame_layout(self.assembler, [r7, s8, s20, r4], [s8, r4, r7, r2],
                        '?')
     assert self.assembler.got([('mov', r4, r2), ('mov', s8, r4),
                                ('mov', r7, s8), ('mov', s20, r7)])
Exemplo n.º 7
0
 def test_cycle(self):
     s8 = frame_pos(8, INT)
     s12 = frame_pos(12, INT)
     s20 = frame_pos(19, INT)
     s24 = frame_pos(1, INT)
     remap_frame_layout(self.assembler, [r4, s8, s20, r7],
                        [s8, r7, r4, s20], '?')
     assert self.assembler.got([('push', s8), ('mov', r4, s8),
                                ('mov', s20, r4), ('mov', r7, s20),
                                ('pop', r7)])
Exemplo n.º 8
0
    def prepare_arguments(self):
        non_float_locs = []
        non_float_regs = []
        float_locs = []
        float_regs = []
        stack_args = []

        arglocs = self.arglocs
        argtypes = self.argtypes

        count = 0                      # stack alignment counter
        on_stack = 0
        for arg in arglocs:
            if arg.type != FLOAT:
                if len(non_float_regs) < len(r.argument_regs):
                    reg = r.argument_regs[len(non_float_regs)]
                    non_float_locs.append(arg)
                    non_float_regs.append(reg)
                else:  # non-float argument that needs to go on the stack
                    count += 1
                    on_stack += 1
                    stack_args.append(arg)
            else:
                if len(float_regs) < len(r.vfp_argument_regs):
                    reg = r.vfp_argument_regs[len(float_regs)]
                    float_locs.append(arg)
                    float_regs.append(reg)
                else:  # float argument that needs to go on the stack
                    if count % 2 != 0:
                        stack_args.append(None)
                        count = 0
                        on_stack += 1
                    stack_args.append(arg)
                    on_stack += 2
        # align the stack
        if count % 2 != 0:
            stack_args.append(None)
            on_stack += 1
        self._push_stack_args(stack_args, on_stack*WORD)
        # Check that the address of the function we want to call is not
        # currently stored in one of the registers used to pass the arguments
        # or on the stack, which we can not access later
        # If this happens to be the case we remap the register to r4 and use r4
        # to call the function
        if self.fnloc in non_float_regs or self.fnloc.is_stack():
            non_float_locs.append(self.fnloc)
            non_float_regs.append(r.r4)
            self.fnloc = r.r4
        # remap values stored in core registers
        remap_frame_layout(self.asm, non_float_locs, non_float_regs, r.ip)
        # remap values stored in vfp registers
        remap_frame_layout(self.asm, float_locs, float_regs, r.vfp_ip)
Exemplo n.º 9
0
 def test_cycle_2(self):
     s8 = frame_pos(8, INT)
     s12 = frame_pos(12, INT)
     s20 = frame_pos(19, INT)
     s24 = frame_pos(1, INT)
     s2 = frame_pos(2, INT)
     s3 = frame_pos(3, INT)
     remap_frame_layout(self.assembler,
                        [r0, s8, r1, s20, r0, s20, s24, r3, s2, s3],
                        [s8, s20, r1, r0, r4, s24, r5, s12, s3, s2], ip)
     assert self.assembler.got([('mov', r0, r4), ('mov', s24, r5),
                                ('mov', r3, s12), ('mov', s20, ip),
                                ('mov', ip, s24), ('push', s8),
                                ('mov', r0, s8), ('mov', s20, r0),
                                ('pop', s20), ('push', s3), ('mov', s2, ip),
                                ('mov', ip, s3), ('pop', s2)])
Exemplo n.º 10
0
    def prepare_arguments(self):
        arglocs = self.arglocs
        reg_args = count_reg_args(arglocs)
        self._collect_and_push_stack_args(arglocs)
        # collect variables that need to go in registers and the registers they
        # will be stored in
        num = 0
        count = 0
        non_float_locs = []
        non_float_regs = []
        float_locs = []
        for i in range(reg_args):
            arg = arglocs[i]
            if arg.type == FLOAT and count % 2 != 0:
                num += 1
                count = 0
            reg = r.caller_resp[num]

            if arg.type == FLOAT:
                float_locs.append((arg, reg))
            else:
                non_float_locs.append(arg)
                non_float_regs.append(reg)

            if arg.type == FLOAT:
                num += 2
            else:
                num += 1
                count += 1
        # Check that the address of the function we want to call is not
        # currently stored in one of the registers used to pass the arguments
        # or on the stack, which we can not access later
        # If this happens to be the case we remap the register to r4 and use r4
        # to call the function
        if not self.fnloc.is_imm():
            non_float_locs.append(self.fnloc)
            non_float_regs.append(r.r4)
            self.fnloc = r.r4
        # remap values stored in core registers
        remap_frame_layout(self.asm, non_float_locs, non_float_regs, r.ip)

        for loc, reg in float_locs:
            self.asm.mov_from_vfp_loc(loc, reg, r.all_regs[reg.value + 1])
Exemplo n.º 11
0
    def prepare_arguments(self):
        arglocs = self.arglocs
        reg_args = count_reg_args(arglocs)
        self._collect_and_push_stack_args(arglocs)
        # collect variables that need to go in registers and the registers they
        # will be stored in
        num = 0
        count = 0
        non_float_locs = []
        non_float_regs = []
        float_locs = []
        for i in range(reg_args):
            arg = arglocs[i]
            if arg.type == FLOAT and count % 2 != 0:
                    num += 1
                    count = 0
            reg = r.caller_resp[num]

            if arg.type == FLOAT:
                float_locs.append((arg, reg))
            else:
                non_float_locs.append(arg)
                non_float_regs.append(reg)

            if arg.type == FLOAT:
                num += 2
            else:
                num += 1
                count += 1
        # Check that the address of the function we want to call is not
        # currently stored in one of the registers used to pass the arguments
        # or on the stack, which we can not access later
        # If this happens to be the case we remap the register to r4 and use r4
        # to call the function
        if self.fnloc in r.argument_regs or self.fnloc.is_stack():
            non_float_locs.append(self.fnloc)
            non_float_regs.append(r.r4)
            self.fnloc = r.r4
        # remap values stored in core registers
        remap_frame_layout(self.asm, non_float_locs, non_float_regs, r.ip)

        for loc, reg in float_locs:
            self.asm.mov_from_vfp_loc(loc, reg, r.all_regs[reg.value + 1])
Exemplo n.º 12
0
 def test_trivial(self):
     remap_frame_layout(self.assembler, [], [], "?")
     assert self.assembler.ops == []
     remap_frame_layout(self.assembler, [r0, r1, r3, r5, r6, r7, r9], [r0, r1, r3, r5, r6, r7, r9], "?")
     assert self.assembler.ops == []
     s8 = frame_pos(1, INT)
     s12 = frame_pos(31, INT)
     s20 = frame_pos(6, INT)
     remap_frame_layout(
         self.assembler, [r0, r1, s20, s8, r3, r5, r6, s12, r7, r9], [r0, r1, s20, s8, r3, r5, r6, s12, r7, r9], "?"
     )
     assert self.assembler.ops == []
Exemplo n.º 13
0
 def test_trivial(self):
     remap_frame_layout(self.assembler, [], [], '?')
     assert self.assembler.ops == []
     remap_frame_layout(self.assembler, [r0, r1, r3, r5, r6, r7, r9],
                        [r0, r1, r3, r5, r6, r7, r9], '?')
     assert self.assembler.ops == []
     s8 = frame_pos(1, INT)
     s12 = frame_pos(31, INT)
     s20 = frame_pos(6, INT)
     remap_frame_layout(self.assembler,
                        [r0, r1, s20, s8, r3, r5, r6, s12, r7, r9],
                        [r0, r1, s20, s8, r3, r5, r6, s12, r7, r9], '?')
     assert self.assembler.ops == []
Exemplo n.º 14
0
    def prepare_arguments(self):
        non_float_locs = []
        non_float_regs = []
        float_locs = []
        float_regs = []
        stack_args = []
        singlefloats = None

        arglocs = self.arglocs
        argtypes = self.argtypes

        count = 0                      # stack alignment counter
        on_stack = 0
        for i in range(len(arglocs)):
            argtype = INT
            if i < len(argtypes) and argtypes[i] == 'S':
                argtype = argtypes[i]
            arg = arglocs[i]
            if arg.is_float():
                argtype = FLOAT
                reg = self.get_next_vfp(argtype)
                if reg:
                    assert len(float_regs) < len(r.vfp_argument_regs)
                    float_locs.append(arg)
                    assert reg not in float_regs
                    float_regs.append(reg)
                else:  # float argument that needs to go on the stack
                    if count % 2 != 0:
                        stack_args.append(None)
                        count = 0
                        on_stack += 1
                    stack_args.append(arg)
                    on_stack += 2
            elif argtype == 'S':
                # Singlefloat argument
                if singlefloats is None:
                    singlefloats = []
                tgt = self.get_next_vfp(argtype)
                if tgt:
                    singlefloats.append((arg, tgt))
                else:  # Singlefloat argument that needs to go on the stack
                       # treated the same as a regular core register argument
                    count += 1
                    on_stack += 1
                    stack_args.append(arg)
            else:
                if len(non_float_regs) < len(r.argument_regs):
                    reg = r.argument_regs[len(non_float_regs)]
                    non_float_locs.append(arg)
                    non_float_regs.append(reg)
                else:  # non-float argument that needs to go on the stack
                    count += 1
                    on_stack += 1
                    stack_args.append(arg)
        # align the stack
        if count % 2 != 0:
            stack_args.append(None)
            on_stack += 1
        self._push_stack_args(stack_args, on_stack*WORD)
        # Check that the address of the function we want to call is not
        # currently stored in one of the registers used to pass the arguments
        # or on the stack, which we can not access later
        # If this happens to be the case we remap the register to r4 and use r4
        # to call the function
        if self.fnloc in non_float_regs or self.fnloc.is_stack():
            non_float_locs.append(self.fnloc)
            non_float_regs.append(r.r4)
            self.fnloc = r.r4
        # remap values stored in vfp registers
        remap_frame_layout(self.asm, float_locs, float_regs, r.vfp_ip)
        if singlefloats:
            for src, dest in singlefloats:
                if src.is_float():
                    assert 0, 'unsupported case'
                if src.is_stack():
                    # use special VLDR for 32bit
                    self.asm.regalloc_mov(src, r.ip)
                    src = r.ip
                if src.is_imm():
                    self.mc.gen_load_int(r.ip.value, src.value)
                    src = r.ip
                if src.is_core_reg():
                    self.mc.VMOV_cs(dest.value, src.value)
        # remap values stored in core registers
        remap_frame_layout(self.asm, non_float_locs, non_float_regs, r.ip)
Exemplo n.º 15
0
 def test_constants2(self):
     c3 = ImmLocation(3)
     s12 = frame_pos(12, INT)
     remap_frame_layout(self.assembler, [c3], [s12], "?")
     assert self.assembler.ops == [("mov", c3, s12)]
Exemplo n.º 16
0
 def test_constants_and_cycle(self):
     c3 = ImmLocation(3)
     s12 = frame_pos(13, INT)
     remap_frame_layout(self.assembler, [r5, c3, s12], [s12, r0, r5], r1)
     assert self.assembler.ops == [("mov", c3, r0), ("push", s12), ("mov", r5, s12), ("pop", r5)]
Exemplo n.º 17
0
 def test_simple_registers(self):
     remap_frame_layout(self.assembler, [r0, r1, r2], [r3, r4, r5], '?')
     assert self.assembler.ops == [('mov', r0, r3), ('mov', r1, r4),
                                   ('mov', r2, r5)]
Exemplo n.º 18
0
 def test_constants_and_cycle(self):
     c3 = ImmLocation(3)
     s12 = frame_pos(13, INT)
     remap_frame_layout(self.assembler, [r5, c3, s12], [s12, r0, r5], r1)
     assert self.assembler.ops == [('mov', c3, r0), ('push', s12),
                                   ('mov', r5, s12), ('pop', r5)]
Exemplo n.º 19
0
 def test_constants2(self):
     c3 = ImmLocation(3)
     s12 = frame_pos(12, INT)
     remap_frame_layout(self.assembler, [c3], [s12], '?')
     assert self.assembler.ops == [('mov', c3, s12)]
Exemplo n.º 20
0
 def test_constants(self):
     c3 = ImmLocation(3)
     remap_frame_layout(self.assembler, [c3], [r0], '?')
     assert self.assembler.ops == [('mov', c3, r0)]
Exemplo n.º 21
0
    def prepare_arguments(self):
        non_float_locs = []
        non_float_regs = []
        float_locs = []
        float_regs = []
        stack_args = []
        singlefloats = None
        longlong_mask = 0

        arglocs = self.arglocs
        argtypes = self.argtypes

        r_register_count = 0
        on_stack = 0

        for i in range(len(arglocs)):
            argtype = INT
            if i < len(argtypes) and argtypes[i] == 'S':
                argtype = argtypes[i]
            arg = arglocs[i]

            if arg.is_float():
                if i < len(argtypes) and argtypes[i] == 'L':
                    # A longlong argument.  It uses two regular argument
                    # positions, but aligned to an even number.  This is
                    # a bit strange, but it is the case even for registers:
                    # it can be in r0-r1 or in r2-r3 but not in r1-r2.
                    assert arg.is_float()
                    if r_register_count == 0:
                        # will temporarily load the register into d8
                        float_locs.append(arg)
                        float_regs.append(r.d8)
                        longlong_mask |= 1
                        r_register_count = 2
                        continue
                    elif r_register_count <= 2:
                        # will temporarily load the register into d9
                        float_locs.append(arg)
                        float_regs.append(r.d9)
                        longlong_mask |= 2
                        r_register_count = 4
                        continue
                    elif r_register_count == 3:
                        r_register_count = 4
                else:
                    # A 64-bit float argument.  Goes into the next free v#
                    # register, or if none, to the stack aligned to an
                    # even number of words.
                    argtype = FLOAT
                    reg = self.get_next_vfp(argtype)
                    if reg:
                        float_locs.append(arg)
                        assert reg not in float_regs
                        float_regs.append(reg)
                        continue
                # float or longlong argument that needs to go on the stack
                if on_stack & 1:  # odd: realign
                    stack_args.append(None)
                    on_stack += 1
                stack_args.append(arg)
                on_stack += 2

            elif argtype == 'S':
                # Singlefloat (32-bit) argument.  Goes into the next free
                # v# register, or if none, to the stack in a single word.
                if singlefloats is None:
                    singlefloats = []
                tgt = self.get_next_vfp(argtype)
                if tgt:
                    singlefloats.append((arg, tgt))
                else:  # Singlefloat argument that needs to go on the stack
                    # treated the same as a regular core register argument
                    stack_args.append(arg)
                    on_stack += 1
            else:
                # Regular one-word argument.  Goes into the next register
                # free from the list r0, r1, r2, r3, or to the stack.
                if r_register_count < len(r.argument_regs):
                    reg = r.argument_regs[r_register_count]
                    r_register_count += 1
                    non_float_locs.append(arg)
                    non_float_regs.append(reg)
                else:  # non-float argument that needs to go on the stack
                    stack_args.append(arg)
                    on_stack += 1

        # align the stack
        if on_stack & 1:  # odd: realign
            stack_args.append(None)
            on_stack += 1
        self._push_stack_args(stack_args, on_stack * WORD)

        # Check that the address of the function we want to call is not
        # currently stored in one of the registers used to pass the arguments
        # or on the stack, which we can not access later
        # If this happens to be the case we remap the register to r4 and use r4
        # to call the function
        if not self.fnloc.is_imm():
            non_float_locs.append(self.fnloc)
            non_float_regs.append(r.r4)
            self.fnloc = r.r4

        # remap values stored in vfp registers
        remap_frame_layout(self.asm, float_locs, float_regs, r.vfp_ip)
        if singlefloats:
            for src, dest in singlefloats:
                if src.is_float():
                    assert 0, 'unsupported case'
                if src.is_stack():
                    # use special VLDR for 32bit
                    self.asm.regalloc_mov(src, r.ip)
                    src = r.ip
                if src.is_imm():
                    self.mc.gen_load_int(r.ip.value, src.value)
                    src = r.ip
                if src.is_core_reg():
                    self.mc.VMOV_cs(dest.value, src.value)

        # remap values stored in core registers
        remap_frame_layout(self.asm, non_float_locs, non_float_regs, r.ip)
        if longlong_mask & 1:
            self.mc.FMRRD(r.r0.value, r.r1.value, r.d8.value)
        if longlong_mask & 2:
            self.mc.FMRRD(r.r2.value, r.r3.value, r.d9.value)
Exemplo n.º 22
0
 def test_constants(self):
     c3 = ImmLocation(3)
     remap_frame_layout(self.assembler, [c3], [r0], "?")
     assert self.assembler.ops == [("mov", c3, r0)]
Exemplo n.º 23
0
    def prepare_arguments(self):
        non_float_locs = []
        non_float_regs = []
        float_locs = []
        float_regs = []
        stack_args = []
        singlefloats = None
        longlong_mask = 0

        arglocs = self.arglocs
        argtypes = self.argtypes

        r_register_count = 0
        on_stack = 0

        for i in range(len(arglocs)):
            argtype = INT
            if i < len(argtypes) and argtypes[i] == 'S':
                argtype = argtypes[i]
            arg = arglocs[i]

            if arg.is_float():
                if i < len(argtypes) and argtypes[i] == 'L':
                    # A longlong argument.  It uses two regular argument
                    # positions, but aligned to an even number.  This is
                    # a bit strange, but it is the case even for registers:
                    # it can be in r0-r1 or in r2-r3 but not in r1-r2.
                    assert arg.is_float()
                    if r_register_count == 0:
                        # will temporarily load the register into d8
                        float_locs.append(arg)
                        float_regs.append(r.d8)
                        longlong_mask |= 1
                        r_register_count = 2
                        continue
                    elif r_register_count <= 2:
                        # will temporarily load the register into d9
                        float_locs.append(arg)
                        float_regs.append(r.d9)
                        longlong_mask |= 2
                        r_register_count = 4
                        continue
                    elif r_register_count == 3:
                        r_register_count = 4
                else:
                    # A 64-bit float argument.  Goes into the next free v#
                    # register, or if none, to the stack aligned to an
                    # even number of words.
                    argtype = FLOAT
                    reg = self.get_next_vfp(argtype)
                    if reg:
                        float_locs.append(arg)
                        assert reg not in float_regs
                        float_regs.append(reg)
                        continue
                # float or longlong argument that needs to go on the stack
                if on_stack & 1:   # odd: realign
                    stack_args.append(None)
                    on_stack += 1
                stack_args.append(arg)
                on_stack += 2

            elif argtype == 'S':
                # Singlefloat (32-bit) argument.  Goes into the next free
                # v# register, or if none, to the stack in a single word.
                if singlefloats is None:
                    singlefloats = []
                tgt = self.get_next_vfp(argtype)
                if tgt:
                    singlefloats.append((arg, tgt))
                else:  # Singlefloat argument that needs to go on the stack
                       # treated the same as a regular core register argument
                    stack_args.append(arg)
                    on_stack += 1
            else:
                # Regular one-word argument.  Goes into the next register
                # free from the list r0, r1, r2, r3, or to the stack.
                if r_register_count < len(r.argument_regs):
                    reg = r.argument_regs[r_register_count]
                    r_register_count += 1
                    non_float_locs.append(arg)
                    non_float_regs.append(reg)
                else:  # non-float argument that needs to go on the stack
                    stack_args.append(arg)
                    on_stack += 1

        # align the stack
        if on_stack & 1:    # odd: realign
            stack_args.append(None)
            on_stack += 1
        self._push_stack_args(stack_args, on_stack*WORD)

        # Check that the address of the function we want to call is not
        # currently stored in one of the registers used to pass the arguments
        # or on the stack, which we can not access later
        # If this happens to be the case we remap the register to r4 and use r4
        # to call the function
        if not self.fnloc.is_imm():
            non_float_locs.append(self.fnloc)
            non_float_regs.append(r.r4)
            self.fnloc = r.r4

        # remap values stored in vfp registers
        remap_frame_layout(self.asm, float_locs, float_regs, r.vfp_ip)
        if singlefloats:
            for src, dest in singlefloats:
                if src.is_float():
                    assert 0, 'unsupported case'
                if src.is_stack():
                    # use special VLDR for 32bit
                    self.asm.regalloc_mov(src, r.ip)
                    src = r.ip
                if src.is_imm():
                    self.mc.gen_load_int(r.ip.value, src.value)
                    src = r.ip
                if src.is_core_reg():
                    self.mc.VMOV_cs(dest.value, src.value)

        # remap values stored in core registers
        remap_frame_layout(self.asm, non_float_locs, non_float_regs, r.ip)
        if longlong_mask & 1:
            self.mc.FMRRD(r.r0.value, r.r1.value, r.d8.value)
        if longlong_mask & 2:
            self.mc.FMRRD(r.r2.value, r.r3.value, r.d9.value)
Exemplo n.º 24
0
 def test_simple_registers(self):
     remap_frame_layout(self.assembler, [r0, r1, r2], [r3, r4, r5], "?")
     assert self.assembler.ops == [("mov", r0, r3), ("mov", r1, r4), ("mov", r2, r5)]