|
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 > |
RE: SHARC 21065 (C compiler call code)
Started by ●March 1, 2005
Reply by ●March 1, 20052005-03-01
|
--On Tuesday, March 01, 2005 10:55 AM +0100 Burgwedel Friedrich <> wrote: > 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; Nitpick: CJUMP isn't a "macro" because it's not expanded by the assembler. It's a true instruction, implemented in the electronics of the chip at full speed, so it takes only one cycle (plus the normal pipeline delays) to execute. Thus the above sequence takes 3 cycles, not 5, to run. If you tried to implement the same sequence piece-meal, you couldn't do it in one instruction because there aren't enough data paths in the chip to accommodate the transfers. But because this is a common sequence in C, ADI implemented the sequence with custom logic to make it fast. I suppose even more of the calling sequence could have been implemented with custom hardware but one reaches diminishing returns when one stops finding uses for the resulting delay slots and the cost of adding extra custom data paths becomes prohibitive. It would be interesting to see what other RISC architectures do for this kind of thing. [Sorry about the double post earlier. My mail client crashed when I hit the Send button and I didn't realize the message went out successfully.] |
Reply by ●March 1, 20052005-03-01
|
> Nitpick: CJUMP isn't a "macro" because it's not expanded by > the assembler. Sure; I missed to say "microcode macros", I just meant macros on an abstract level -- the word "somehow" should have expressed this. > -----Original Message----- > From: Kenneth Porter [mailto:] > Sent: Tuesday, March 01, 2005 2:44 PM > To: > Subject: RE: [adsp] SHARC 21065 (C compiler call code) > > --On Tuesday, March 01, 2005 10:55 AM +0100 Burgwedel Friedrich > <> wrote: > > > 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; > > Nitpick: CJUMP isn't a "macro" because it's not expanded by > the assembler. > It's a true instruction, implemented in the electronics of > the chip at full > speed, so it takes only one cycle (plus the normal pipeline > delays) to > execute. Thus the above sequence takes 3 cycles, not 5, to run. > > If you tried to implement the same sequence piece-meal, you > couldn't do it > in one instruction because there aren't enough data paths in > the chip to > accommodate the transfers. But because this is a common > sequence in C, ADI > implemented the sequence with custom logic to make it fast. I > suppose even > more of the calling sequence could have been implemented with custom > hardware but one reaches diminishing returns when one stops > finding uses > for the resulting delay slots and the cost of adding extra > custom data > paths becomes prohibitive. It would be interesting to see > what other RISC > architectures do for this kind of thing. > > [Sorry about the double post earlier. My mail client crashed > when I hit the > Send button and I didn't realize the message went out successfully.] |
Reply by ●March 1, 20052005-03-01
|
--On Tuesday, March 01, 2005 3:09 PM +0100 Burgwedel Friedrich <> wrote: > Sure; I missed to say "microcode macros", I just meant macros on an > abstract level -- the word "somehow" should have expressed this. Does it in fact use microcode? I thought this architecture, being RISC-like, was pure logic, and that CJUMP just used special data paths. |
Reply by ●March 1, 20052005-03-01
|
Hello I need to write and read data from file. I use the following code, but it doesn't work for writing.I don't know how to read in a file fread? Help would be greatly appreciated. #include <stdlib.h> #include <stdio.h> #include <string.h> char dfilename[32] = "default.txt"; int toto=9; FILE *fpr; // Test for writing fpr= fopen(dfilename,"w"); fprintf(fpr, "Test \n"); fprintf(fpr," ;%d; \n",toto); fclose(fpr); // Test for writing fpr= fopen(dfilename,"r"); freadf(); fclose(fpr); |
Reply by ●March 1, 20052005-03-01
|
> Does it in fact use microcode? I thought this architecture, being > RISC-like, was pure logic, and that CJUMP just used special > data paths. I think you are right -- using microcode would require at least one additional cycle, otherwise it could be done simply by logic -- and would therefore decrease the maximum core clock rate. As I said -- macro on an abstract level; don't mind how it is implemented. So long, Friedrich > -----Original Message----- > From: Kenneth Porter [mailto:] > Sent: Tuesday, March 01, 2005 5:53 PM > To: > Subject: RE: [adsp] SHARC 21065 (C compiler call code) |
Reply by ●March 1, 20052005-03-01
|
--On Tuesday, March 01, 2005 6:36 PM +0100 wrote: > I need to write and read data from file. This implies that you have hardware to implement a filesystem. Are you talking about within the debugger, or some other environment? Did you look at the explanation in the library manual for how the debugger supports file I/O? (It's non-trivial, but a prerequisite to discussion.) |
Reply by ●March 1, 20052005-03-01
|
--On Tuesday, March 01, 2005 6:40 PM +0100 Burgwedel Friedrich <> wrote: > As I said -- macro on an abstract level; don't mind how it is > implemented. I only nitpick here because I've been led astray myself by false assumptions, and "macro" suggests text replacement, which is clearly not the case here. I just don't want the bystanders less familiar with the nuts and bolts to go down the wrong ally. ;) |
Reply by ●March 1, 20052005-03-01
|
I'm working in simulation session only, no Ez-Kit at this time. Is it a problem? Selon Kenneth Porter <>: > > --On Tuesday, March 01, 2005 6:36 PM +0100 > wrote: > > > I need to write and read data from file. > > This implies that you have hardware to implement a filesystem. Are you > talking about within the debugger, or some other environment? Did you look > at the explanation in the library manual for how the debugger supports file > I/O? (It's non-trivial, but a prerequisite to discussion.) > > |
Reply by ●March 1, 20052005-03-01
|
--On Tuesday, March 01, 2005 7:49 PM +0100 wrote: > I'm working in simulation session only, no Ez-Kit at this time. Is it a > problem? That's essentially the same as the debugger, so you should be fine. I think you have to enable stdio support in the debugger somewhere. (I've left the company where I used this so this is from memory.) |






