-----Original Message----- From: Burgwedel Friedrich Sent: Tuesday, March 01, 2005 10:56 AM To: 'Mike Rosing'; wadsworth_bob Cc: Subject: RE: [adsp] SHARC 21065 (C compiler call code) Hi Mike, hi Bob, > So it looks like you do a look up into a table, then jump to > some offset from that address, and fix the registers i6 and > i7 along the way. It's from a C compiler, so you may want to > find the original source code to figure out what is really going on. not completely... ;) The cjump opcode is, as mike said, intended for the compiler's use. It is normally hidden in the ccall() macro, which normally expands to cjump function (DB); dm(i7,m7)=r2; dm(i7,m7)=PC; Since cjump itself is a macro somehow, the whole sequence expands to r2 = i6; i6 = i7; jump function (db) dm(i7,m7) = r2; dm(i7,m7) = PC; This is the compiler's function call code. Knowing that the C compiler uses i7 as stack pointer and i6 as frame base pointer (remember the stack to grow downwards!), we see that the code simply sets a new stack frame base at the position of the current stack pointer (that is, i6 now addresses free memory on the stack), then pushes the old frame base pointer and the current program counter to the stack; this way they will occupy the first two locations of a new stack frame. If the called function needs some additional memory on the stack (for local variables and temporary register backup, for example), it uses modify (i7,-x); with x being the number of words that will be usable in the stack frame. The real stack frame is always 2 words larger, due to the two push operations inside the call code: dm(0,i6) addresses the old frame base pointer (pushed first), and dm(-1,i6) addresses the address from where the function was called (not exactly the return address, see down). This is why all later local variables or register backups will have to address dm(-2,i6) to dm(-x-1,i6). Even the function parameters that where pushed to the stack (if any) are easily addressed by offsets to the frame base pointer: dm(1,i6) addresses the last pushed parameter -- normally the first parameter in the parameter list. dm(2,i6) addresses the 2nd parameter, ... The C call code is complemented by the c runtime function exit macro, which is i12 = dm(m7,i6); jump (m14,i12) (db); rframe; nop; which in turn expands to i12 = dm(-1,i6); jump (1,i12) (db); i7 = i6; i6 = dm(0,i6) This expanded version misses the nop opcode which is normally "recycled" by the optimizer, but I show the expanded (less optimal) code for better understanding. As you can see, this code reverses the changes made by the call code: it retrieves the "to be" return address and jumps back to caller by incrementing the address by one since it was pushed by the last opcode of the call code; so execution resumes just after the call code. The next two operations just restore the stack pointer and the frame base pointer -- we even to not need to manually reverse the modify operation that generated the stack frame. Quite simple, right?! For those who code assembly language I should mention that fetching the return address causes a DAG2 stall; you should try to insert another opcode -- maybe restoring a DAG1 register that would otherwise stall, too -- to hide this stall. So long, Friedrich > -----Original Message----- > From: Mike Rosing [mailto:] > Sent: Tuesday, March 01, 2005 5:03 AM > To: wadsworth_bob > Cc: > Subject: Re: [adsp] SHARC 21065 > > On Mon, 28 Feb 2005, wadsworth_bob wrote: > > > I am using the SHARC 21065 processor. At the end of some > of the code > > I have inherited, the following code exists: > > > > _exit: > > i12=dm(m7,i6); > > jump (m14,i12) (db); > > rframe; > > nop; > > .ENDSEG; > > > > Can anyone tell me what this is for? > > The manual says the following: > > CJUMP |function | (PC, <reladdr24>) | (DB); > RFRAME; > > Function: > The CJUMP instruction is generated by the C compiler for > function calls, and is not intended for use in assembly > language programs. CJUMP combines a direct or PC-relative > jump with register transfer operations that save the frame > and stack pointers. The RFRAME instruction reversed the > register transfers to restore the frame and stack pointers. > > ... > > instruction what it does > > CJUMP function(DB) JUMP function (DB), R2=I6, I6=I7; > > RFRAME; I7 = I6, I6 = DM(0,I6) > > So it looks like you do a look up into a table, then jump to > some offset from that address, and fix the registers i6 and > i7 along the way. It's from a C compiler, so you may want to > find the original source code to figure out what is really going on. > > Patience, persistence, truth, > Dr. mike > |
FW: SHARC 21065 (C compiler call code)
Started by ●March 1, 2005