cik@l.cc.purdue.edu.UUCP (01/01/87)
Many times I have found it necessary to include asm instructions in a C program. It should be possible to do this in such a way that the compiler will substitute the locations of variables for the variable names in the asm instructions. I know of ways to do the job; one person to whom I showed this pointed out that if the compiler were changed this could break. This would not be the case if the suggested enhancement were made. -- (Usual disclaimer line.) Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907 Phone: (317)494-6054 (decvax,ihnp4,uiucdcs)!pur-ee!stat-l!cik (decwrl,hplabs,ucbvax)!purdue!stat-l!cik hrubin@l.cc.purdue.edu
greg@utcsri.UUCP (Gregory Smith) (01/06/87)
In article <488@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes: > >Many times I have found it necessary to include asm instructions >in a C program. It should be possible to do this in such a way >that the compiler will substitute the locations of variables for >the variable names in the asm instructions. I know of ways to do >the job; one person to whom I showed this pointed out that if the >compiler were changed this could break. This would not be the case >if the suggested enhancement were made. Yes. Someone suggested a 'printf-like' capability for asm() a while back. EG on a 68000 machine, to get the user stack pointer in supervisor code: ... char *user_sp; ... asm(" move usp,%a", user_sp ); '%a' would change either to (1) the appropriate extern name (eg "_user_sp"), if user_sp were external, (2) the appropriate local symbol if user_sp were local static, or (3) the appropriate stack-indexed or frame-indexed address if user_sp were auto. The above code would then be immune to a large class of compiler changes. In particular, changes to (1) name translation conventions, (2) local symbol allocation method, (3) stack allocation and addressing conventions. Other bells and whistles could be added, but this would be the most useful feature. Of course, different features would be useful with different machines.
guy%gorodish@Sun.COM (Guy Harris) (01/06/87)
> >Many times I have found it necessary to include asm instructions > >in a C program. It should be possible to do this in such a way > >that the compiler will substitute the locations of variables for > >the variable names in the asm instructions. I know of ways to do > >the job; one person to whom I showed this pointed out that if the > >compiler were changed this could break. This would not be the case > >if the suggested enhancement were made. > > Yes. Someone suggested a 'printf-like' capability for asm() a while back. > EG on a 68000 machine, to get the user stack pointer in supervisor code: The WE32K compiler that AT&T-IS puts out has what looks like a rather nice new kind of "asm" facility. To quote from the release notes from S5R2.1 on the 3B2: The enhanced "asm" facility allows the user to define constructs that look like static C functions. Each "asm" macro has one definition and zero or more uses per source file. The definition must appear in the same file with the uses (or be #included), and the same "asm" macro can be defined multiply (and differently) in several files. The "asm" macro definition declares a return type for the macro code, specifies patterns for the formal parameters, and provides bodies of code to expand when the patterns match. When it encounters an "asm" macro call, the compiler replaces uses of the formal parameters by its idea of the assembly language locations of the actual arguments as it expands the code body. The uses of an "asm" macro look like normal C function calls. They can be used in expressions and they can return values. The arguments to an "asm" macro can be arbitrary expressions, except that they can not contain uses of the same or other "asm" macros. When the argument to an "asm" macro is a function name or structure, the compiler generates code to compute a pointer to the structure or function, and the resulting pointer is used as the actual argument of the macro. The example they give: asm void SPL(newpri) { % reg newpri; spl newpri % con newpri; movw newpri,%r0 spl %r0 } This says that "SPL" is a function returning no value and taking one argument. If the argument is in a register, it just generates an "spl" instruction using that register. If it's a constant, it generates a "movw" to move it into r0 and then generates an "spl" using r0. The set of storage modes it recognizes are: "treg" - a compiler-selected temporary register. "ureg" - a register variable. "reg" - a "treg" or "ureg". "con" - a compile-time constant. "mem" - any allowed machine addressing mode, including "reg" and "con". "lab" - a new label. This is not used with a formal parameter; it causes a new label to be generated. "error" - generates an error. This is used if code cannot be generated for certain operand types. If a value is returned, the code generated by the macro must "do the right thing", e.g. return the value in the register used for function return values. So if you say SPL(3); it will generate movw &3,%r0 spl %r0 The example given for getting the user stack pointer from supervisor mode on a 68K would look something like: asm char * get_user_sp() { movec usp,a0 } (assuming an implementation where pointer types are returned in A0). If you wanted something that copied the user SP into its argument (this is a function that modifies its argument - "asm" functions can do this), it would read like asm void get_user_sp(user_sp) { % reg user_sp; movec usp,user_sp % mem user_sp; movec usp,a0 movea a0,user_sp } (I am assuming that this would just generate a "movec" if "user_sp" was a register and the "movec"/"movea" pair otherwise).