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