[ixp1200] using addresses of labels

Cyrus Hall hallcp at cs.colorado.edu
Tue May 27 20:42:44 EDT 2003


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




More information about the ixp1200 mailing list