-void DefineData (ExprDesc* Expr)
-/* Output a data definition for the given expression */
-{
- switch (ED_GetLoc (Expr)) {
-
- case E_LOC_ABS:
- /* Absolute: numeric address or const */
- g_defdata (TypeOf (Expr->Type) | CF_CONST, Expr->IVal, 0);
- break;
-
- case E_LOC_GLOBAL:
- /* Global variable */
- g_defdata (CF_EXTERNAL, Expr->Name, Expr->IVal);
- break;
-
- case E_LOC_STATIC:
- case E_LOC_LITERAL:
- /* Static variable or literal in the literal pool */
- g_defdata (CF_STATIC, Expr->Name, Expr->IVal);
- break;
-
- case E_LOC_REGISTER:
- /* Register variable. Taking the address is usually not
- * allowed.
- */
- if (IS_Get (&AllowRegVarAddr) == 0) {
- Error ("Cannot take the address of a register variable");
- }
- g_defdata (CF_REGVAR, Expr->Name, Expr->IVal);
- break;
-
- default:
- Internal ("Unknown constant type: 0x%04X", ED_GetLoc (Expr));
- }
-}
-
-
-
-static void LoadConstant (unsigned Flags, ExprDesc* Expr)
-/* Load the primary register with some constant value. */
-{
- switch (ED_GetLoc (Expr)) {
-
- case E_LOC_ABS:
- /* Number constant */
- g_getimmed (Flags | TypeOf (Expr->Type) | CF_CONST, Expr->IVal, 0);
- break;
-
- case E_LOC_GLOBAL:
- /* Global symbol, load address */
- g_getimmed ((Flags | CF_EXTERNAL) & ~CF_CONST, Expr->Name, Expr->IVal);
- break;
-
- case E_LOC_STATIC:
- case E_LOC_LITERAL:
- /* Static symbol or literal, load address */
- g_getimmed ((Flags | CF_STATIC) & ~CF_CONST, Expr->Name, Expr->IVal);
- break;
-
- case E_LOC_REGISTER:
- /* Register variable. Taking the address is usually not
- * allowed.
- */
- if (IS_Get (&AllowRegVarAddr) == 0) {
- Error ("Cannot take the address of a register variable");
- }
- g_getimmed ((Flags | CF_REGVAR) & ~CF_CONST, Expr->Name, Expr->IVal);
-
- case E_LOC_STACK:
- g_leasp (Expr->IVal);
- break;
-
- default:
- Internal ("Unknown constant type: %04X", Expr->Flags);
- }
-}
-
-
-
-static int kcalc (token_t tok, long val1, long val2)
-/* Calculate an operation with left and right operand constant. */
-{
- switch (tok) {
- case TOK_EQ:
- return (val1 == val2);
- case TOK_NE:
- return (val1 != val2);
- case TOK_LT:
- return (val1 < val2);
- case TOK_LE:
- return (val1 <= val2);
- case TOK_GE:
- return (val1 >= val2);
- case TOK_GT:
- return (val1 > val2);
- case TOK_OR:
- return (val1 | val2);
- case TOK_XOR:
- return (val1 ^ val2);
- case TOK_AND:
- return (val1 & val2);
- case TOK_SHR:
- return (val1 >> val2);
- case TOK_SHL:
- return (val1 << val2);
- case TOK_STAR:
- return (val1 * val2);
- case TOK_DIV:
- if (val2 == 0) {
- Error ("Division by zero");
- return 0x7FFFFFFF;
- }
- return (val1 / val2);
- case TOK_MOD:
- if (val2 == 0) {
- Error ("Modulo operation with zero");
- return 0;
- }
- return (val1 % val2);
- default:
- Internal ("kcalc: got token 0x%X\n", tok);
- return 0;
- }
-}
-
-
-