1 /*****************************************************************************/
5 /* Load an expression into the primary register */
9 /* (C) 2004 Ullrich von Bassewitz */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
45 /*****************************************************************************/
47 /*****************************************************************************/
51 static void LoadConstant (unsigned Flags, ExprDesc* Expr)
52 /* Load the primary register with some constant value. */
54 switch (ED_GetLoc (Expr)) {
58 g_getimmed (Flags | TypeOf (Expr->Type) | CF_CONST, Expr->IVal, 0);
62 /* Global symbol, load address */
63 g_getimmed ((Flags | CF_EXTERNAL) & ~CF_CONST, Expr->Name, Expr->IVal);
68 /* Static symbol or literal, load address */
69 g_getimmed ((Flags | CF_STATIC) & ~CF_CONST, Expr->Name, Expr->IVal);
73 /* Register variable. Taking the address is usually not
76 if (IS_Get (&AllowRegVarAddr) == 0) {
77 Error ("Cannot take the address of a register variable");
79 g_getimmed ((Flags | CF_REGVAR) & ~CF_CONST, Expr->Name, Expr->IVal);
87 Internal ("Unknown constant type: %04X", Expr->Flags);
93 void LoadExpr (unsigned Flags, struct ExprDesc* Expr)
94 /* Load an expression into the primary register if it is not already there. */
96 if (ED_IsLVal (Expr)) {
98 /* Dereferenced lvalue */
99 Flags |= TypeOf (Expr->Type);
100 if (ED_NeedsTest (Expr)) {
104 switch (ED_GetLoc (Expr)) {
107 /* Absolute: numeric address or const */
108 g_getstatic (Flags | CF_ABSOLUTE, Expr->IVal, 0);
112 /* Global variable */
113 g_getstatic (Flags | CF_EXTERNAL, Expr->Name, Expr->IVal);
118 /* Static variable or literal in the literal pool */
119 g_getstatic (Flags | CF_STATIC, Expr->Name, Expr->IVal);
123 /* Register variable */
124 g_getstatic (Flags | CF_REGVAR, Expr->Name, Expr->IVal);
128 /* Value on the stack */
129 g_getlocal (Flags, Expr->IVal);
133 /* The primary register - just test if necessary */
134 if (Flags & CF_TEST) {
140 /* Reference to address in primary with offset in Expr */
141 g_getind (Flags, Expr->IVal);
145 Internal ("Invalid location in LoadExpr: 0x%04X", ED_GetLoc (Expr));
148 /* Expression was tested */
153 if (ED_IsLocExpr (Expr)) {
154 if (Expr->IVal != 0) {
155 /* We have an expression in the primary plus a constant
156 * offset. Adjust the value in the primary accordingly.
158 Flags |= TypeOf (Expr->Type);
159 g_inc (Flags | CF_CONST, Expr->IVal);
162 /* Constant of some sort, load it into the primary */
163 LoadConstant (Flags, Expr);
166 /* Are we testing this value? */
167 if (ED_NeedsTest (Expr)) {
168 /* Yes, force a test */
169 Flags |= TypeOf (Expr->Type);