gcc-specific constructions
** Single-update per instruction on lpcreg
The indirect threading is enabled by configuring with
--enable-threading.
Basically, all instructions are now declared in a file called
xsb_inst_list.h, structured as:
XSB_INST(inum, instr, label, op1type, op2type, op3type, op4type);
where:
inum is the number of the instruction;
instr is the constant name of the instruction;
label is the corresponding label in emuloop;
op?type are the types of the operands
XSB_INST is just a name for a macro which is redefined each
time we need to include this file. This is done both in inst_xsb.c, to
initialize inst_table, and inside emuloop.c, to initialize the array
with the addresses of instructions.
Unfortunatelly, we still need to declare the number of the
instructions in inst_xsb.h. Note that we could generate that from the
above structure, but that would require some kind of
pre-pre-processing (or at least I couldn't figure out how to do it
without using m4 or the like). Also, we need to include both the name
of the instruction (instr) and the corresponding label ini the
definition; that's because the names are going to be already defined
as their numbers, when xsb_inst_list.h is included. If somebody has
any suggestions to overcome these "problems", please let me know.
Continuing... in emuloop, instructions are now defined between
calls to XSB_Start_Instr(instr, label); and XSB_Next_Instr();. These
macros are expanded to, either labels and indirect goto's if compiling
with indirect threading, or cases of a switch and goto contcases
otherwise.
The other change I made is regarding the handling of operands
f instructions. The goal is to reduce the number of updates
(increments) to lpcreg in each instruction. So, I created macros which
will use displacements from lpcreg to get the arguments, and to
advance lpcreg according to the size of the instruction+operands.
As an example, here is the definition of getpvar:
XSB_Start_Instr(getpvar,_getpvar); /* PVR */
Op1(Variable(get_xvx));
Op2(Register(get_xxr));
ADVANCE_PC(size_xxx);
/* trailing is needed here because this instruction can also be
generated *after* the occurrence of the first call - kostis */
bind_copy((CPtr)op1, op2); /* In WAM bld_copy() */
XSB_Next_Instr();