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