1

我正在尝试在 y86 代码中展开循环,但是当我尝试运行测试程序时,我得到了 2 个不同的值。注册。代码是:

    xorq %rax,%rax      # count = 0;
    andq %rdx,%rdx      # len <= 0?
    jle Done        # if so, goto Done:

Loop:   
    mrmovq (%rdi), %r10 # read val from src...
    rmmovq %r10, (%rsi) # ...and store it to dst
    andq %r10, %r10     # val <= 0?
    jle Npos        # if so, goto Npos:
    #irmovq $1, %r10
    #addq %r10, %rax        
    iaddq $1, %rax      # count++
Npos:   
    irmovq $1, %r10
    subq %r10, %rdx     # len--
    #irmovq $8, %r10
    #addq %r10, %rdi        
    #addq %r10, %rsi        
    iaddq $8, %rdi      # src++
    iaddq $8, %rsi      # dst++
    andq %rdx,%rdx      # len > 0?
    jg Loop         # if so, goto Loop:
Done:
    ret

我制作的展开版本是:

xorq %rax,%rax      # count = 0;
    andq %rdx,%rdx      # len <= 0?
    jle Done        # if so, goto Done:

Loop:   
    mrmovq (%rdi), %r10     # read val from src…
    mrmovq 8(%rdi), %r11    # <- from class get second value
    rmmovq %r10, (%rsi)     # ...and store it to dst
    rmmovq %r11, 8(%rsi)         # store second val to dst
    andq %r10, %r10     # val <= 0?
    jle Npos            # if so, goto Npos:
    iaddq $1, %rax

Npos:   
    andq %r11, %r11 # check if src[1] <= 0
    jle Npos2       # if it is, don’t increase count
    iaddq $1, %rax

Npos2: 
    irmvoq %2, %r10
    iaddq $16, %rdi     # increase stack or base pointer to get next 2 vals
    iaddq $16, %rsi     # increase stack or base pointer to store next 2 vals
    subq %r10, %rdx     # decrease length by 2
    jge Loop            # go back into loop if length >= 2

len_cleanup:
    iaddq $2, %rdx

cleanup:
    irmovq $1, %r10
    subq %r10, %rdx
    jl Done             # if length < 0, jmp to Done, no cleanup needed
    mrmovq (%rdi), %r10     # get next val
    rmmovq %r10, (%rsi)     # move val onto stack
    andq %r10, %r10     # check if val <= 0
    jle Done            # skip count if val < 0
    iaddq $1, %rax      # same as iaddq $1, %rax

Done: 
    ret

我应该得到的结果是 2,但从展开的结果返回的结果是 3。我知道有一个额外的iaddq被执行,但我不确定在哪里。我将循环展开两次,以便改为检查 2 个值。

4

1 回答 1

1

我刚刚修好了。我想在开始循环之前减少 %rdx 以正确展开函数。

当您不知道迭代计数是展开因子的倍数时,您需要展开类似的do{ }while(--i >= 0);东西
--i; do { }while(i-=2 >= 0);以确保您不会过冲。

于 2016-10-26T01:42:38.193 回答