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