Currently I find that whenever I reread the descriptions, in tcc-doc and tcc.h, of the various VT values I find myself understanding how they work worse afterwards than before. I'm not sure how the descriptions achieve this level of confusiveness; I think it's perhaps because of the way the descriptions mix source and target, meaning and use, and how a term like "lvalue" sometimes means the pointer and sometimes the thing pointed to, and how the terms "lvalue", "pointer" and "reference" are used without any clear distinction.
I don't know that I can do any better, but here's an attempt. Perhaps someone can suggest improvements. The r (and r2) fields of SValue record how and where a value is stored. The value or r is one of the following base values possibly bitwise ORed with some of the following flags. # Base values A register number, from 0 to VT_CONST - 1. The value is in the register. VT_CONST The value is a constant, stored in SValue.c. VT_LOCAL The value is an offset on the stack, typically the address of a local variable. The offset is stored in SValue.c.i. VT_LLOCAL The same as VT_LOCAL but with another level of indirection. VT_LLOCAL is only used together with VT_LVAL to mean that the value is pointed to by an address on the stack. This typically arises when a (register | VT_LVAL) has to be saved to the stack, but it also can come from an architecture-specific calling convention. VT_CMP The value is 0 or 1 and represented in the processor flags. The way it is represented is indicated in SValue.c.i. VT_JMP VT_JMPI ... # Flags VT_LVAL Add one level of indirection. So (register | VT_LVAL) means the value is pointed to by an address in a register, and (VT_LOCAL | VT_LVAL) means the value is pointed to by an offset on the stack, in other words, that the value is on the stack, for example the value of a local variable. VT_REF Add another level of indirection. So (VT_LOCAL | VT_LVAL | VT_REF) means the value is pointed to by a value on the stack. VT_REF is only used together with VT_LVAL, and currently it is only used together with VT_LOCAL and only when the value is a structure. VT_REF must not be used together with VT_LLOCAL. (VT_LOCAL | VT_LVAL | VT_REF) means the same as (VT_LLOCAL | VT_LVAL) but the two are currently used in different parts of the code. VT_SYM The symbol SValue.sym must be added to the value. VT_SYM is only used together with VT_CONST. VT_MUSTCAST Used together with a register value to indicate that an integer stored in a register must be cast to the value type if the value is used (lazy casting). VT_LVAL_BYTE VT_LVAL_SHORT VT_LVAL_UNSIGNED I don't properly understand these. The current description is: "if the lvalue has an integer type then these flags give its real type. The type alone is not enough in case of cast optimisations." Presumably "the lvalue" means "the value, which is stored in memory", but what does "real type" mean? It sounds very philosophical. Perhaps the description ought to be something like: When VT_LVAL is set, these flags must also be set appropriately to indicate the size and sign of the value stored in memory. Who knows? _______________________________________________ Tinycc-devel mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/tinycc-devel
