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