RE: [ixp1200] using addresses of labels
Hi Cyrus, Use the JUMP instruction: jump[register, label#], targets [label1, label2, ...labeln], optional_token Also, you may find the .func_table directive useful for your needs. If wanted, you can export the labels addresses to core applications with the .export_func directive. take care, Arthur -----Original Message----- From: Cyrus Hall [mailto:hallcp@cs.colorado.edu] Sent: Wednesday, May 14, 2003 1:28 AM To: ixp1200 List Subject: [ixp1200] using addresses of labels Hi there all- I'm currently trying to build a table of address to parts of a filter I've written. IE, you have a value, index into the table, and jump to the associated address in code. The jumping is simple enough, save the PC and replace it, give up control, and wait for the ctx switch back in. Not hyper efficient, but not bad when you're only filter one or two fields. Returning is simple enough as well. The problem I'm having is actually get the address of code. This clearly needs to be done at compile time (there doesn't appear to be a linker involved in loading code onto the ME's), and would seem to be as simple as replacing the symbolic label with it's final address. Yet, there seems to be no way to do something like: immed32[var, label#:] Has anyone done anything like this and\or know how? Thanks, Cyrus
Arthur- Thanks, that does exactly what I need. I unfortunately missed it the first couple times through the ISA. Cyrus On Wed, 2003-05-14 at 01:33, Arthur Berkovitch wrote:
Hi Cyrus, Use the JUMP instruction:
jump[register, label#], targets [label1, label2, ...labeln], optional_token
Also, you may find the .func_table directive useful for your needs. If wanted, you can export the labels addresses to core applications with the .export_func directive. take care, Arthur
-----Original Message----- From: Cyrus Hall [mailto:hallcp@cs.colorado.edu] Sent: Wednesday, May 14, 2003 1:28 AM To: ixp1200 List Subject: [ixp1200] using addresses of labels
Hi there all-
I'm currently trying to build a table of address to parts of a filter I've written. IE, you have a value, index into the table, and jump to the associated address in code. The jumping is simple enough, save the PC and replace it, give up control, and wait for the ctx switch back in. Not hyper efficient, but not bad when you're only filter one or two fields. Returning is simple enough as well.
The problem I'm having is actually get the address of code. This clearly needs to be done at compile time (there doesn't appear to be a linker involved in loading code onto the ME's), and would seem to be as simple as replacing the symbolic label with it's final address. Yet, there seems to be no way to do something like:
immed32[var, label#:]
Has anyone done anything like this and\or know how?
Thanks, Cyrus
Sorry to have such an extended reply time, but I've just now gotten to the point where I'm in need of another small pointer. I've messed around with jump for the last week with little success, and rtn seems to require use of the .func_table directive. But the documentation for .func_table and .export_func amounts to a single paragraph a piece and I can't find a place either one is used in the code provided with the ENP2505. Do you by change have a small snippet of example code? My biggest issue with all the methods I've tried: there seems to be no way to setup a function address and then jump to it at run time. Now, since one can't self modify the ucode store, this wouldn't seem to be needed, but it would sure make my life during debugging a hell of a lot easier. Any suggestions? thanks, Cy On Wed, 2003-05-14 at 01:33, Arthur Berkovitch wrote:
Hi Cyrus, Use the JUMP instruction:
jump[register, label#], targets [label1, label2, ...labeln], optional_token
Also, you may find the .func_table directive useful for your needs. If wanted, you can export the labels addresses to core applications with the .export_func directive. take care, Arthur
-----Original Message----- From: Cyrus Hall [mailto:hallcp@cs.colorado.edu] Sent: Wednesday, May 14, 2003 1:28 AM To: ixp1200 List Subject: [ixp1200] using addresses of labels
Hi there all-
I'm currently trying to build a table of address to parts of a filter I've written. IE, you have a value, index into the table, and jump to the associated address in code. The jumping is simple enough, save the PC and replace it, give up control, and wait for the ctx switch back in. Not hyper efficient, but not bad when you're only filter one or two fields. Returning is simple enough as well.
The problem I'm having is actually get the address of code. This clearly needs to be done at compile time (there doesn't appear to be a linker involved in loading code onto the ME's), and would seem to be as simple as replacing the symbolic label with it's final address. Yet, there seems to be no way to do something like:
immed32[var, label#:]
Has anyone done anything like this and\or know how?
Thanks, Cyrus
Had any luck with this? I've gotten to the point where I need to turn this huge macro I have into a function but the assembler complains: find_create.uc(146) : ERROR: No initialized return address found in code\ for rtn opcode. find_create.uc(146) : ERROR: No initialized return address found in code\ for rtn opcode. Not only is the documentation for rtn a joke, it doesn't look like its used hardly anywhere in any of the provided microcode. The problem seems to be that you can't write the address of the label into external memory and get it back out, because then the register allocator can't properly trace the code. Without a way to put labels into external memory, its seems the only choise is using another context sensitive register, but I'm running out of those as it is. Najati
On Tue, 2003-05-27 at 17:37, Najati Imam wrote:
Had any luck with this? I've gotten to the point where I need to turn this
Yea I have, more details below...
huge macro I have into a function but the assembler complains:
find_create.uc(146) : ERROR: No initialized return address found in code\ for rtn opcode. find_create.uc(146) : ERROR: No initialized return address found in code\ for rtn opcode.
Not only is the documentation for rtn a joke, it doesn't look like its used hardly anywhere in any of the provided microcode.
This has been the theme of my last 3 months: poor documentation and lack of good example code that utilizes a majority of the IXP1200 features. I'm sure the Intel reps on this list have heard it before (IE, sorry to be pissy), but 1000+ pages of docs are useless when they appear to have been written by a technical writer who didn't have all the information they needed. Some of its great, but never the parts you need. I think that's some sort of CS law, no?
The problem seems to be that you can't write the address of the label into external memory and get it back out, because then the register allocator can't properly trace the code. Without a way to put labels into external memory, its seems the only choise is using another context sensitive register, but I'm running out of those as it is.
I've played with two solutions to the issue at hand. Although I got the code that used rtn working correctly, in the end I didn't feel like keeping all the unused code warnings the assembler spit out at me. These are created since the assembler has no way to know where you are branching to. Here was the hack: scratch[read, $jmp_loc[0], jtbl_addr, offset, 1], ctx_swap immed[$jmp_loc[0], 0] //the trick rtn[$jmp_loc[0]] Thankfully, the assembler isn't smart enough to catch that your "initialization" of $jmp_loc[0] is not going to overwrite that value that comes out in the next line of code (the rtn), as read and write xfer registers are actually separate. My code ran great using that hack, but I was concerned that it might break down the road, as it seems like a total violation of the ISA's intended use. My original try had used the jump instruction, so I went back to it. Jump takes an offset from a known label, so now when you create your address tables you need to also do a subtraction. This unfortunately almost doubles the size of jump table creation. Here is some example code: #macro JumpTblAddr[label, dest] load_addr[jmp_addr, label] alu[dest, jmp_addr, -, base_addr] #endm #macro BuildJumpTbl[ ] xbuf_alloc($tbl, 8) .local jmp_addr base_addr addr load_addr[base_addr, extract_base#] JumpTblAddr[extract_ethernet#, $tbl[0]] JumpTblAddr[extract_arp#, $tbl[1]] JumpTblAddr[extract_ip#, $tbl[2]] JumpTblAddr[extract_icmp#, $tbl[3]] JumpTblAddr[extract_igmp#, $tbl[4]] JumpTblAddr[extract_udp#, $tbl[5]] JumpTblAddr[extract_tcp#, $tbl[6]] immed[addr, _JTBL_PKT_TYPES] scratch[write, $tbl[0], addr, 0, 7], ctx_swap .endlocal #endm ... scratch[read, $extract_addr[0], jtbl_addr, 0, 1], ctx_swap jump[$extract_addr[1], base#], targets[etherall_dest_addr#, etherall_src_addr#, etherall_length_type#, ether802_dsap#, ether802_ssap#, ether802_cntl#, ether802_org#, ether802_type#] Note that since you list the targets with the jump instruction, the assembler can now build a control flow diagram and no longer spits out warnings. Would have been nice if jump has rtn's functionality with a targets list. Hope that all helps. If you can find a solution to get rid of the subtraction in JumpTblAddr I would love to hear it. It seems that a label at the very start of the ucode might do nicely... Cy
participants (3)
-
Arthur Berkovitch
-
Cyrus Hall
-
Najati Imam