![](https://secure.gravatar.com/avatar/e726143691e607ec32925f7ead38f864.jpg?s=120&d=mm&r=g)
The first solution certainly works, and I used to use it when I only had a single call point, but now I have need for fairly separated call points for this given code, and need to get data both in to and out of the subroutine (a "return value" if you will). I'm low on code store, and the subroutine is rather large, so a macro is out of the question. I gave the second solution a shot, after adding a branch around the code so it wouldn't execute when included. IE: br[after_include#] #include "file.uc" after_include#: However, I continue to get the same errors. The compiler still considers the variable initialized in the macro as separate from those (with the same name) in the subroutine. IE, "WARNGING: GPR, 'ret_addr', was referenced, but never assigned to," from within subroutine. It would appear that the .local directive is being ignored, although the compiler does not complain. I went back and re-read section 2.2.7 of the Microcode Programmer's Reference Manual, and it would seem that your suggestion *should* actually be working. However, I would guess that uca implements macros by simple cut-past and substitute, so it's not considered to be part of the .local declaration. I also took a look at how the microC complier handles function calls, only to find that it too uses global registers. Needless to say, I don't have many unused registers left either, and I'm trying to avoid the losing one of them for the entire code space as hard as I can. Thanks, Cy On Wed, 2003-08-13 at 15:37, Johnson, Erik J wrote:
I wouldn't think you would have to make it global, but certainly you would have to make the live range through the subroutine (which make sense from the functionality you want to achieve). I am stuck in a hotel right now and don't have access to the assembler, but I would guess that the following would work
.local rtn_addr load_addr[rtn_addr, ret_loc#] br[sub_func#] ret_loc#: //...other code...
.subroutine sub_func#: //does neat stuff rtn[rtn_addr] .endsub .endlocal
Of course, there are drawbacks to this as well. The rtn_addr is live for the "other code", but perhaps you can re-arrange the code to fix this "problem" as follows:
Some ".h" file
.local rtn_addr #macro my_sub_func[] load_addr[rtn_addr, ret_loc#] br[sub_func#] ret_loc#:
.subroutine sub_func#: //does neat stuff rtn[rtn_addr] .endsub .endlocal
Some .uc file #include "my.h"
my_sub_func[] // other code
Wow, now I really wish I had the assembler with me because I probably am just fooling myself into thinking this works...
erik
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Erik J. Johnson Intel Research & Development erik.j.johnson@intel.com NOT SPEAKING FOR INTEL ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-----Original Message----- From: Cyrus Hall [mailto:hallcp@cs.colorado.edu] Sent: Wednesday, August 13, 2003 2:07 PM To: ixp1200 List Subject: [ixp1200] Frustration with subroutines...
A general question in regards to "passing" registers to branch points. Here is what I would love to be able to do:
.local rtn_addr load_addr[rtn_addr, ret_loc#] br[sub_func#] ret_loc#: .endlocal //...other code...
.subroutine sub_func#: //does neat stuff rtn[rtn_addr] .endsub
IE, I want to declare a variable->register mapping and then be able to use that same register in a subroutine. I've tried fooling around with the .subroutine structures assembly with no luck. Only if rtn_addr is live for the entire program does that work. Is there anyway to control live ranges when using subroutines, or will uca force one to waste a register by making it global?
Thanks, Cy