.\" $Id$ .TL Addition of register variables to an existing table. .NH 1 Introduction .PP This is a short description of the newest feature in the table driven code generator for the Amsterdam Compiler Kit. It describes how to add register variables to an existing table. This assumes a distribution of October 1983 or later. It is not clear whether one should read this when starting with a table for a new machine, or waiting till the table is well debugged already. .NH 1 Modifications to the table itself. .NH 2 Register section .PP Just before the properties of the register one of the following can be added: .IP - 2 regvar .IP - regvar ( pointer ) .IP - regvar ( loop ) .IP - regvar ( float ) .LP All register variables of one type must be of the same size, and they may have no subregisters. .NH 2 Codesection .PP .IP - 2 Two pseudo functions are added to the list allowed inside expressions: .RS .IP 1) 3 inreg ( expr ) has as a parameter the offset of a local, and returns 0,1 or 2: .RS .IP 2: 3 if the variable is in a register. .IP 1: if the variable could be in a register but isn't. .IP 0: if the variable cannot be in a register. .RE .IP 2) regvar ( expr ) returns the register associated with the variable. Undefined if it is not in a register. So regvar ( expr ) is defined if and only if inreg (expr ) == 2. .RE .IP - It is now possible to remove() a register expression, this is of course needed for a store into a register local. .IP - The return out of a procedure may now involve register restores, so the special word 'return' in the table will invoke a user defined function. .NH 1 Modifications to mach.c .PP If register variables are used in a table, the program .I cgg will define the word REGVARS during compilation of the sources. So the following functions described here should be bracketed by #ifdef REGVARS and #endif. .IP - 2 regscore(off,size,typ,freq,totyp) long off; .br This function should assign a score to a register variable, the score should preferably be the estimated number of bytes gained when it is put in a register. Off and size are the offset and size of the variable, typ is the type, that is reg_any, reg_pointer, reg_loop or reg_float. Freq is the number of times it occurs statically, and totyp is the type of the register it is planned to go into. .br Keep in mind that the gain should be net, that is the cost for register save/restore sequences and the cost of initialisation in the case of parameters should already be included. .IP - i_regsave() .br This function is called at the start of a procedure, just before register saves are done. It can be used to initialise some variables if needed. .IP - f_regsave() .br This function is called at end of the register save sequence. It can be used to do the real saving if multiple register move instructions are available. .IP - regsave(regstr,off,size) char *regstr; long off; .br Should either do the real saving or set up a table to have it done by f_regsave. Note that initialisation of parameters should also be done, or planned here. .IP - regreturn() .br Should restore saved registers and return. The function result is already in the function return area by now. .NH 1 Examples .PP Here are some examples out of the PDP 11 table .DS lol inreg($1)==2| | | regvar($1) | | lil inreg($1)==2| | | {regdef2, regvar($1)} | | stl inreg($1)==2| xsource2 | remove(regvar($1)) move(%[1],regvar($1)) | | | inl inreg($1)==2| | remove(regvar($1)) "inc %(regvar($1)%)" setcc(regvar($1)) | | | .DE .NH 1 Afterthoughts. .PP At the time of this writing the tables for the PDP 11 and the M68000 and the VAX are converted, in all cases the two byte wordsize versions. No big problems have occurred, but experience has shown that it is necessary to check the table carefully for all patterns with locals in them. Code may be generated that uses the memoryslot the local is not in.