CPW Part 13: Code Generation for Expressions
Cleanup: Renaming printSymtab
The naming printSymtab is inconsistent. Rename the function printSymTab().
Extending the Code Generation Interface
In the interface for code generation we should offer an unary minus instruction. We can provide this as a two address instruction where both operands are registers. With the instruction the first register gets inverted and the result stored in the second registers.
In the header file we define a new enum constant GEN_UNARYMINUS_R that belongs to a new group of two address instructions. We also declare a function genOp2r() for this type of instructions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #ifndef ABC_GEN_H
#define ABC_GEN_H
// ...
// supported instruction
enum GenOp
{
GEN_OP2R_BEGIN,
GEN_UNARYMINUS_R, // new: for unary minus instruction
GEN_OP2R_END,
GEN_OP3R_BEGIN = GEN_OP2R_END,
GEN_ADD_R = GEN_OP3R_BEGIN, // addition
GEN_SUB_R, // subtraction
GEN_IMUL_R, // multiplication
GEN_DIV_R, // division
GEN_MOD_R, // modulo
GEN_OP3R_END,
GEN_OP3I_BEGIN = GEN_OP3R_END,
GEN_ADD_I = GEN_OP3I_BEGIN,
GEN_SUB_I,
GEN_IMUL_I,
GEN_DIV_I,
GEN_MOD_I,
GEN_OP3I_END,
};
// new: 2 address instructions
void genOp2r(enum GenOp op, GenReg reg0, GenReg reg1);
// ...
#endif // ABC_GEN_H
|
The implementation of genOp2r() uses the zero register to support the unary minus operation. For example genOp2r(GEN_UNARYMINUS_R, 8, 9) generates
1 | subq %8, %0, %9
|
The implementation of loadExpr() of course should use genOp2r() where appropriate.
Extending the Expression Interface
The interface should provide a method for loading the address of an l-value expression into a register:
1 2 3 4 5 6 7 8 9 10 11 | #ifndef ABC_EXPR_H
#define ABC_EXPR_H
// ...
// methods
// ...
void loadExprAddr(const struct Expr *expr, GenReg dest); // l-value required
// ...
#endif // ABC_EXPR_H
|
The implementation can simply trigger an assertion failure if the expression is not an l-value. Such a semantic check can be done beforehand by the parser where an error message with line and column information can be generated.