Makefile.in: always run "make alldeps" when "make dist"
[platform/upstream/nasm.git] / exprlib.c
1 /* ----------------------------------------------------------------------- *
2  *   
3  *   Copyright 1996-2009 The NASM Authors - All Rights Reserved
4  *   See the file AUTHORS included with the NASM distribution for
5  *   the specific copyright holders.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following
9  *   conditions are met:
10  *
11  *   * Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer.
13  *   * Redistributions in binary form must reproduce the above
14  *     copyright notice, this list of conditions and the following
15  *     disclaimer in the documentation and/or other materials provided
16  *     with the distribution.
17  *     
18  *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19  *     CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  *     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  *     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  *     DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23  *     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  *     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  *     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  *     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  *     OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  *     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * ----------------------------------------------------------------------- */
33
34 /*
35  * exprlib.c
36  *
37  * Library routines to manipulate expression data types.
38  */
39
40 #include "nasm.h"
41
42 /*
43  * Return true if the argument is a simple scalar. (Or a far-
44  * absolute, which counts.)
45  */
46 int is_simple(expr * vect)
47 {
48     while (vect->type && !vect->value)
49         vect++;
50     if (!vect->type)
51         return 1;
52     if (vect->type != EXPR_SIMPLE)
53         return 0;
54     do {
55         vect++;
56     } while (vect->type && !vect->value);
57     if (vect->type && vect->type < EXPR_SEGBASE + SEG_ABS)
58         return 0;
59     return 1;
60 }
61
62 /*
63  * Return true if the argument is a simple scalar, _NOT_ a far-
64  * absolute.
65  */
66 int is_really_simple(expr * vect)
67 {
68     while (vect->type && !vect->value)
69         vect++;
70     if (!vect->type)
71         return 1;
72     if (vect->type != EXPR_SIMPLE)
73         return 0;
74     do {
75         vect++;
76     } while (vect->type && !vect->value);
77     if (vect->type)
78         return 0;
79     return 1;
80 }
81
82 /*
83  * Return true if the argument is relocatable (i.e. a simple
84  * scalar, plus at most one segment-base, plus possibly a WRT).
85  */
86 int is_reloc(expr * vect)
87 {
88     while (vect->type && !vect->value)  /* skip initial value-0 terms */
89         vect++;
90     if (!vect->type)            /* trivially return true if nothing */
91         return 1;               /* is present apart from value-0s */
92     if (vect->type < EXPR_SIMPLE)       /* false if a register is present */
93         return 0;
94     if (vect->type == EXPR_SIMPLE) {    /* skip over a pure number term... */
95         do {
96             vect++;
97         } while (vect->type && !vect->value);
98         if (!vect->type)        /* ...returning true if that's all */
99             return 1;
100     }
101     if (vect->type == EXPR_WRT) {       /* skip over a WRT term... */
102         do {
103             vect++;
104         } while (vect->type && !vect->value);
105         if (!vect->type)        /* ...returning true if that's all */
106             return 1;
107     }
108     if (vect->value != 0 && vect->value != 1)
109         return 0;               /* segment base multiplier non-unity */
110     do {                        /* skip over _one_ seg-base term... */
111         vect++;
112     } while (vect->type && !vect->value);
113     if (!vect->type)            /* ...returning true if that's all */
114         return 1;
115     return 0;                   /* And return false if there's more */
116 }
117
118 /*
119  * Return true if the argument contains an `unknown' part.
120  */
121 int is_unknown(expr * vect)
122 {
123     while (vect->type && vect->type < EXPR_UNKNOWN)
124         vect++;
125     return (vect->type == EXPR_UNKNOWN);
126 }
127
128 /*
129  * Return true if the argument contains nothing but an `unknown'
130  * part.
131  */
132 int is_just_unknown(expr * vect)
133 {
134     while (vect->type && !vect->value)
135         vect++;
136     return (vect->type == EXPR_UNKNOWN);
137 }
138
139 /*
140  * Return the scalar part of a relocatable vector. (Including
141  * simple scalar vectors - those qualify as relocatable.)
142  */
143 int64_t reloc_value(expr * vect)
144 {
145     while (vect->type && !vect->value)
146         vect++;
147     if (!vect->type)
148         return 0;
149     if (vect->type == EXPR_SIMPLE)
150         return vect->value;
151     else
152         return 0;
153 }
154
155 /*
156  * Return the segment number of a relocatable vector, or NO_SEG for
157  * simple scalars.
158  */
159 int32_t reloc_seg(expr * vect)
160 {
161     while (vect->type && (vect->type == EXPR_WRT || !vect->value))
162         vect++;
163     if (vect->type == EXPR_SIMPLE) {
164         do {
165             vect++;
166         } while (vect->type && (vect->type == EXPR_WRT || !vect->value));
167     }
168     if (!vect->type)
169         return NO_SEG;
170     else
171         return vect->type - EXPR_SEGBASE;
172 }
173
174 /*
175  * Return the WRT segment number of a relocatable vector, or NO_SEG
176  * if no WRT part is present.
177  */
178 int32_t reloc_wrt(expr * vect)
179 {
180     while (vect->type && vect->type < EXPR_WRT)
181         vect++;
182     if (vect->type == EXPR_WRT) {
183         return vect->value;
184     } else
185         return NO_SEG;
186 }