]> git.sur5r.net Git - cc65/blob - src/cc65/exprdesc.h
Move the test flags into the Flags bitset of struct ExprDesc
[cc65] / src / cc65 / exprdesc.h
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                exprdesc.h                                 */
4 /*                                                                           */
5 /*                      Expression descriptor structure                      */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2002-2004 Ullrich von Bassewitz                                       */
10 /*               Römerstraße 52                                              */
11 /*               D-70794 Filderstadt                                         */
12 /* EMail:        uz@cc65.org                                                 */
13 /*                                                                           */
14 /*                                                                           */
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.                                    */
18 /*                                                                           */
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:                            */
22 /*                                                                           */
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              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #ifndef EXPRDESC_H
37 #define EXPRDESC_H
38
39
40
41 #include <string.h>
42
43 /* common */
44 #include "inline.h"
45
46 /* cc65 */
47 #include "datatype.h"
48
49
50
51 /*****************************************************************************/
52 /*                                   Data                                    */
53 /*****************************************************************************/
54
55
56
57 /* Defines for the flags field of the expression descriptor */
58 enum {
59     /* Location: Where is the value we're talking about? */
60     E_MASK_LOC          = 0x00FF,
61     E_LOC_ABS           = 0x0001,       /* Absolute: numeric address or const */
62     E_LOC_GLOBAL        = 0x0002,       /* Global variable */
63     E_LOC_STATIC        = 0x0004,       /* Static variable */
64     E_LOC_REGISTER      = 0x0008,       /* Register variable */
65     E_LOC_STACK         = 0x0010,       /* Value on the stack */
66     E_LOC_PRIMARY       = 0x0020,       /* The primary register */
67     E_LOC_EXPR          = 0x0040,       /* An expression in the primary register */
68     E_LOC_LITERAL       = 0x0080,       /* Literal in the literal pool */
69
70     /* Constant location of some sort (only if rval) */
71     E_LOC_CONST         = E_LOC_ABS | E_LOC_GLOBAL | E_LOC_STATIC |
72                           E_LOC_REGISTER | E_LOC_LITERAL,
73
74     /* Reference? */
75     E_MASK_RTYPE        = 0x0100,
76     E_RTYPE_RVAL        = 0x0000,
77     E_RTYPE_LVAL        = 0x0100,
78
79     /* Test */
80     E_NEED_TEST         = 0x0200,       /* Expression needs a test to set cc */
81     E_CC_SET            = 0x0400        /* Condition codes are set */
82 };
83
84 /* Describe the result of an expression */
85 typedef struct ExprDesc ExprDesc;
86 struct ExprDesc {
87     struct SymEntry*    Sym;    /* Symbol table entry if known */
88     type*               Type;   /* Type array of expression */
89     long                Val;    /* Value if expression constant */
90     unsigned short      Flags;
91     unsigned long       Name;   /* Name or label number */
92 };
93
94
95
96 /*****************************************************************************/
97 /*                                   Code                                    */
98 /*****************************************************************************/
99
100
101
102 ExprDesc* ED_Init (ExprDesc* Expr);
103 /* Initialize an ExprDesc */
104
105 #if defined(HAVE_INLINE)
106 INLINE int ED_GetLoc (const ExprDesc* Expr)
107 /* Return the location flags from the expression */
108 {
109     return (Expr->Flags & E_MASK_LOC);
110 }
111 #else
112 #  define ED_GetLoc(Expr)       ((Expr)->Flags & E_MASK_LOC)
113 #endif
114
115 #if defined(HAVE_INLINE)
116 INLINE int ED_IsLocAbs (const ExprDesc* Expr)
117 /* Return true if the expression is an absolute value */
118 {
119     return (Expr->Flags & E_MASK_LOC) == E_LOC_ABS;
120 }
121 #else
122 #  define ED_IsLocAbs(Expr)     (((Expr)->Flags & E_MASK_LOC) == E_LOC_ABS)
123 #endif
124
125 #if defined(HAVE_INLINE)
126 INLINE int ED_IsLocRegister (const ExprDesc* Expr)
127 /* Return true if the expression is located in a register */
128 {
129     return (Expr->Flags & E_MASK_LOC) == E_LOC_REGISTER;
130 }
131 #else
132 #  define ED_IsLocRegister(Expr)    (((Expr)->Flags & E_MASK_LOC) == E_LOC_REGISTER)
133 #endif
134
135 #if defined(HAVE_INLINE)
136 INLINE int ED_IsLocStack (const ExprDesc* Expr)
137 /* Return true if the expression is located on the stack */
138 {
139     return (Expr->Flags & E_MASK_LOC) == E_LOC_STACK;
140 }
141 #else
142 #  define ED_IsLocStack(Expr)     (((Expr)->Flags & E_MASK_LOC) == E_LOC_STACK)
143 #endif
144
145 #if defined(HAVE_INLINE)
146 INLINE int ED_IsLocPrimary (const ExprDesc* Expr)
147 /* Return true if the expression is an expression in the register pseudo variable */
148 {
149     return (Expr->Flags & E_MASK_LOC) == E_LOC_PRIMARY;
150 }
151 #else
152 #  define ED_IsLocPrimary(Expr)  (((Expr)->Flags & E_MASK_LOC) == E_LOC_PRIMARY)
153 #endif
154
155 #if defined(HAVE_INLINE)
156 INLINE int ED_IsLocExpr (const ExprDesc* Expr)
157 /* Return true if the expression is an expression in the primary */
158 {
159     return (Expr->Flags & E_MASK_LOC) == E_LOC_EXPR;
160 }
161 #else
162 #  define ED_IsLocExpr(Expr)     (((Expr)->Flags & E_MASK_LOC) == E_LOC_EXPR)
163 #endif
164
165 #if defined(HAVE_INLINE)
166 INLINE int ED_IsLocLiteral (const ExprDesc* Expr)
167 /* Return true if the expression is a string from the literal pool */
168 {
169     return (Expr->Flags & E_MASK_LOC) == E_LOC_LITERAL;
170 }
171 #else
172 #  define ED_IsLocLiteral(Expr)   (((Expr)->Flags & E_MASK_LOC) == E_LOC_LITERAL)
173 #endif
174
175 #if defined(HAVE_INLINE)
176 INLINE int ED_IsLocConst (const ExprDesc* Expr)
177 /* Return true if the expression is a constant location of some sort */
178 {
179     return (Expr->Flags & E_LOC_CONST) != 0;
180 }
181 #else
182 #  define ED_IsLocConst(Expr)  (((Expr)->Flags & E_LOC_CONST) != 0)
183 #endif
184
185 #if defined(HAVE_INLINE)
186 INLINE int ED_IsLVal (const ExprDesc* Expr)
187 /* Return true if the expression is a reference */
188 {
189     return (Expr->Flags & E_MASK_RTYPE) == E_RTYPE_LVAL;
190 }
191 #else
192 #  define ED_IsLVal(Expr)       (((Expr)->Flags & E_MASK_RTYPE) == E_RTYPE_LVAL)
193 #endif
194
195 #if defined(HAVE_INLINE)
196 INLINE int ED_IsRVal (const ExprDesc* Expr)
197 /* Return true if the expression is a rvalue */
198 {
199     return (Expr->Flags & E_MASK_RTYPE) == E_RTYPE_RVAL;
200 }
201 #else
202 #  define ED_IsRVal(Expr)       (((Expr)->Flags & E_MASK_RTYPE) == E_RTYPE_RVAL)
203 #endif
204
205 #if defined(HAVE_INLINE)
206 INLINE void ED_MakeLVal (ExprDesc* Expr)
207 /* Make the expression a lvalue. */
208 {
209     Expr->Flags |= E_RTYPE_LVAL;
210 }
211 #else
212 #  define ED_MakeLVal(Expr)     do { (Expr)->Flags |= E_RTYPE_LVAL; } while (0)
213 #endif
214
215 #if defined(HAVE_INLINE)
216 INLINE void ED_MakeRVal (ExprDesc* Expr)
217 /* Make the expression a rvalue. */
218 {
219     Expr->Flags &= ~E_RTYPE_LVAL;
220 }
221 #else
222 #  define ED_MakeRVal(Expr)     do { (Expr)->Flags &= ~E_RTYPE_LVAL; } while (0)
223 #endif
224
225 #if defined(HAVE_INLINE)
226 INLINE void ED_MarkForTest (ExprDesc* Expr)
227 /* Mark the expression for a test. */
228 {
229     Expr->Flags |= E_NEED_TEST;
230 }
231 #else
232 #  define ED_MarkForTest(Expr)  do { (Expr)->Flags |= E_NEED_TEST; } while (0)
233 #endif
234
235 #if defined(HAVE_INLINE)
236 INLINE int ED_NeedsTest (const ExprDesc* Expr)
237 /* Check if the expression needs a test. */
238 {
239     return (Expr->Flags & E_NEED_TEST) != 0;
240 }
241 #else
242 #  define ED_NeedsTest(Expr)    (((Expr)->Flags & E_NEED_TEST) != 0)
243 #endif
244
245 #if defined(HAVE_INLINE)
246 INLINE void ED_TestDone (ExprDesc* Expr)
247 /* Mark the expression as tested and condition codes set. */
248 {
249     Expr->Flags = (Expr->Flags & ~E_NEED_TEST) | E_CC_SET;
250 }
251 #else
252 #  define ED_TestDone(Expr)     \
253     do { (Expr)->Flags = ((Expr)->Flags & ~E_NEED_TEST) | E_CC_SET; } while (0)
254 #endif
255
256 #if defined(HAVE_INLINE)
257 INLINE int ED_IsTested (const ExprDesc* Expr)
258 /* Check if the expression has set the condition codes. */
259 {
260     return (Expr->Flags & E_CC_SET) != 0;
261 }
262 #else
263 #  define ED_IsTested(Expr)   (((Expr)->Flags & E_CC_SET) != 0)
264 #endif
265
266 #if defined(HAVE_INLINE)
267 INLINE void ED_MarkAsUntested (ExprDesc* Expr)
268 /* Mark the expression as not tested (condition codes not set). */
269 {
270     Expr->Flags &= ~E_CC_SET;
271 }
272 #else
273 #  define ED_MarkAsUntested(Expr)   do { (Expr)->Flags &= ~E_CC_SET; } while (0)
274 #endif
275
276 const char* ED_GetLabelName (const ExprDesc* Expr, long Offs);
277 /* Return the assembler label name of the given expression. Beware: This
278  * function may use a static buffer, so the name may get "lost" on the second
279  * call to the function.
280  */
281
282 int ED_GetStackOffs (const ExprDesc* Expr, int Offs);
283 /* Get the stack offset of an address on the stack in Expr taking into account
284  * an additional offset in Offs.
285  */
286
287 ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, type* Type);
288 /* Make Expr an absolute const with the given value and type. */
289
290 ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value);
291 /* Make Expr a constant integer expression with the given value */
292
293 ExprDesc* ED_MakeRValExpr (ExprDesc* Expr);
294 /* Convert Expr into a rvalue which is in the primary register without an
295  * offset.
296  */
297
298 ExprDesc* ED_MakeLValExpr (ExprDesc* Expr);
299 /* Convert Expr into a lvalue which is in the primary register without an
300  * offset.
301  */
302
303 int ED_IsConst (const ExprDesc* Expr);
304 /* Return true if the expression denotes a constant of some sort. This can be a
305  * numeric constant, the address of a global variable (maybe with offset) or
306  * similar.
307  */
308
309 int ED_IsConstAbs (const ExprDesc* Expr);
310 /* Return true if the expression denotes a constant absolute value. This can be
311  * a numeric constant, cast to any type.
312  */
313
314 int ED_IsConstAbsInt (const ExprDesc* Expr);
315 /* Return true if the expression is a constant (numeric) integer. */
316
317 int ED_IsNullPtr (const ExprDesc* Expr);
318 /* Return true if the given expression is a NULL pointer constant */
319
320 int ED_IsBool (const ExprDesc* Expr);
321 /* Return true of the expression can be treated as a boolean, that is, it can
322  * be an operand to a compare operation.
323  */
324
325 void PrintExprDesc (FILE* F, ExprDesc* Expr);
326 /* Print an ExprDesc */
327
328 type* ReplaceType (ExprDesc* Expr, const type* NewType);
329 /* Replace the type of Expr by a copy of Newtype and return the old type string */
330
331
332
333 /* End of exprdesc.h */
334 #endif
335
336
337