Hardware loop end address

Any technical questions about the Epiphany chip and Parallella HW Platform.

Moderator: aolofsson

Hardware loop end address

Postby upcFrost » Thu Mar 22, 2018 9:29 am

I've started implementing hardware loops into my LLVM backend, and ran into particular problem. Well, not problem, but misunderstanding maybe.

In the arch reference, we have the following example (page 67):

Code: Select all
    mov r1, %low(loop_start);
    movt r1, %high(loop_start);
    movts ls, r1; //setting loop start address
    mov r1, %low(loop_end);
    movt r1, %high(loop_end);
    movts le, r1; //setting loop end address
    mov r1, #0x10;
    movts lc, r1; //setting loop count
    gid; //disabling interrupts
.balignw 8,0x01a2; //align to 8-byte boundary
    add.l r1, r1, r0; //first instruction in loop
    add.l r2, r2, r0; //”.l” forces 32 bit instruction
    add.l r3, r3, r0;
    add.l r4, r4, r0;
    add.l r5, r5, r0;
    add.l r6, r6, r0;
.balignw 8,0x01a2; //align to 8-byte boundary
    add.l r7, r7, r0;
    add.l r8, r8, r0; //last instruction

This example implies that the instruction at "loop_end" label will be executed before jumping back. Here is the code I've got from my backend:

Code: Select all
00000360 <main>:
 360:   000b 0002       mov r0,0x0
 364:   210b 0602       mov r1,0x6008
 368:   120b 0032       mov r0,0x390
 36c:   000b 1002       movt r0,0x0
 370:   190f 0002       movts ls,r0
 374:   178b 0032       mov r0,0x3bc
 378:   000b 1002       movt r0,0x0
 37c:   1d0f 0002       movts le,r0
 380:   028b 0002       mov r0,0x14
 384:   150f 0002       movts lc,r0
 388:   0392            gid
 38a:   01a2            nop
 38c:   01a2            nop
 38e:   01a2            nop
 390:   409b 0000       add r2,r0,1
 394:   055c 0100       str r0,[r1,-0x2]
 398:   44dc 0100       str r2,[r1,-0x1]
 39c:   411b 0000       add r2,r0,2
 3a0:   445c 0000       str r2,[r1]
 3a4:   419b 0000       add r2,r0,3
 3a8:   44dc 0000       str r2,[r1,+0x1]
 3ac:   421b 0000       add r2,r0,4
 3b0:   029b 0000       add r0,r0,5
 3b4:   01a2            nop
 3b6:   01a2            nop
 3b8:   261b 0002       add r1,r1,20
 3bc:   455c 0000       str r2,[r1,+0x2]
 3c0:   000b 0002       mov r0,0x0
 3c4:   194f 0402       rts

Loop end is pointing at 0x3bc (set on 0x374). But when I'm running the code in debugger it actually jump to loop begin (0x390, set on 0x368) before executing the instruction, resulting in smth like

Code: Select all
0x6000: 0x00000014      0x00000015      0x00000016      0x00000017
0x6010: 0x00000000      0x00000019      0x0000001a      0x0000001b
0x6020: 0x0000001c      0x00000000      0x0000001e      0x0000001f

Is it my misunderstanding, or e-GDB bug, or the arch ref is incorrect?
Current LLVM backend for Epiphany: https://github.com/upcFrost/Epiphany. Commits and code reviews are welcome
Posts: 35
Joined: Wed May 28, 2014 6:37 am
Location: Moscow, Russia

Re: Hardware loop end address

Postby jar » Fri Mar 23, 2018 4:08 pm

Your generated assembly is somewhat hard to follow. At first it seems like you're trying to add incremented values in an array...

This is the body of the loop which will be iterated:
Code: Select all
 390:   409b 0000       add r2,r0,1       ; r2 = r0 + 1
 394:   055c 0100       str r0,[r1,-0x2]  ; r1[-2] = r0
 398:   44dc 0100       str r2,[r1,-0x1]  ; r1[-1] = r2
 39c:   411b 0000       add r2,r0,2       ; r2 = r0 + 2
 3a0:   445c 0000       str r2,[r1]       ; r1[0] = r2
 3a4:   419b 0000       add r2,r0,3       ; r2 = r0 + 3
 3a8:   44dc 0000       str r2,[r1,+0x1]  ; r1[1] = r2
 3ac:   421b 0000       add r2,r0,4       ; r2 = r0 + 4
 3b0:   029b 0000       add r0,r0,5       ; r0 += 5
 3b4:   01a2            nop
 3b6:   01a2            nop
 3b8:   261b 0002       add r1,r1,20      ; r1 += 20
 3bc:   455c 0000       str r2,[r1,+0x2]  ; r1[2] = r2;

I don't understand why it adds 20 to the r1 pointer then 8 (+0x2) bytes on top of that. Shouldn't the order be switched so that it stores a value before updating the pointer?

Without working it out on paper, your result looks correct. The "str r2,[r1,+0x2]" store will be overwritten by the next loop.

I might be wrong.
User avatar
Posts: 292
Joined: Mon Dec 17, 2012 3:27 am

Re: Hardware loop end address

Postby olajep » Wed Apr 04, 2018 1:41 pm

There's a test for exactly this in the simulator testsuite:
https://github.com/adapteva/epiphany-bi ... /hwloops.s

Did you try to run your program with e-run --trace, alternatively passing 'sim trace' to e-gdb?

Unfortunately it looks like the instruction the $le register points to is not executed when stepping through the program with 'stepi', or setting a breakpoint at it.
But note that the breakpoint is hit, although gdb reports the wrong address.
Not sure if this is easy to fix, seems we need to tell GDB that the instruction at $LE was in fact a branch instruction, dynamically. Hope I'm wrong otherwise ugh!

// Ola
_start = 266470723;
Posts: 126
Joined: Mon Dec 17, 2012 3:24 am
Location: Sweden

Return to Epiphany and Parallella Q & A

Who is online

Users browsing this forum: No registered users and 4 guests