blob: af022b892d70289365c270c7355b691aa0f98880 [file] [log] [blame]
H. Peter Anvin87f252a2007-09-19 21:40:37 -07001/*
2 * exprlib.c
3 *
4 * Library routines to manipulate expression data types.
5 */
6
7#include "nasm.h"
8
9/*
H. Peter Anvin6867acc2007-10-10 14:58:45 -070010 * Return true if the argument is a simple scalar. (Or a far-
H. Peter Anvin87f252a2007-09-19 21:40:37 -070011 * absolute, which counts.)
12 */
13int is_simple(expr * vect)
14{
15 while (vect->type && !vect->value)
16 vect++;
17 if (!vect->type)
18 return 1;
19 if (vect->type != EXPR_SIMPLE)
20 return 0;
21 do {
22 vect++;
23 } while (vect->type && !vect->value);
24 if (vect->type && vect->type < EXPR_SEGBASE + SEG_ABS)
25 return 0;
26 return 1;
27}
28
29/*
H. Peter Anvin6867acc2007-10-10 14:58:45 -070030 * Return true if the argument is a simple scalar, _NOT_ a far-
H. Peter Anvin87f252a2007-09-19 21:40:37 -070031 * absolute.
32 */
33int is_really_simple(expr * vect)
34{
35 while (vect->type && !vect->value)
36 vect++;
37 if (!vect->type)
38 return 1;
39 if (vect->type != EXPR_SIMPLE)
40 return 0;
41 do {
42 vect++;
43 } while (vect->type && !vect->value);
44 if (vect->type)
45 return 0;
46 return 1;
47}
48
49/*
H. Peter Anvin6867acc2007-10-10 14:58:45 -070050 * Return true if the argument is relocatable (i.e. a simple
H. Peter Anvin87f252a2007-09-19 21:40:37 -070051 * scalar, plus at most one segment-base, plus possibly a WRT).
52 */
53int is_reloc(expr * vect)
54{
55 while (vect->type && !vect->value) /* skip initial value-0 terms */
56 vect++;
H. Peter Anvin6867acc2007-10-10 14:58:45 -070057 if (!vect->type) /* trivially return true if nothing */
H. Peter Anvin87f252a2007-09-19 21:40:37 -070058 return 1; /* is present apart from value-0s */
H. Peter Anvin6867acc2007-10-10 14:58:45 -070059 if (vect->type < EXPR_SIMPLE) /* false if a register is present */
H. Peter Anvin87f252a2007-09-19 21:40:37 -070060 return 0;
61 if (vect->type == EXPR_SIMPLE) { /* skip over a pure number term... */
62 do {
63 vect++;
64 } while (vect->type && !vect->value);
H. Peter Anvin6867acc2007-10-10 14:58:45 -070065 if (!vect->type) /* ...returning true if that's all */
H. Peter Anvin87f252a2007-09-19 21:40:37 -070066 return 1;
67 }
68 if (vect->type == EXPR_WRT) { /* skip over a WRT term... */
69 do {
70 vect++;
71 } while (vect->type && !vect->value);
H. Peter Anvin6867acc2007-10-10 14:58:45 -070072 if (!vect->type) /* ...returning true if that's all */
H. Peter Anvin87f252a2007-09-19 21:40:37 -070073 return 1;
74 }
75 if (vect->value != 0 && vect->value != 1)
76 return 0; /* segment base multiplier non-unity */
77 do { /* skip over _one_ seg-base term... */
78 vect++;
79 } while (vect->type && !vect->value);
H. Peter Anvin6867acc2007-10-10 14:58:45 -070080 if (!vect->type) /* ...returning true if that's all */
H. Peter Anvin87f252a2007-09-19 21:40:37 -070081 return 1;
H. Peter Anvin6867acc2007-10-10 14:58:45 -070082 return 0; /* And return false if there's more */
H. Peter Anvin87f252a2007-09-19 21:40:37 -070083}
84
85/*
H. Peter Anvin6867acc2007-10-10 14:58:45 -070086 * Return true if the argument contains an `unknown' part.
H. Peter Anvin87f252a2007-09-19 21:40:37 -070087 */
88int is_unknown(expr * vect)
89{
90 while (vect->type && vect->type < EXPR_UNKNOWN)
91 vect++;
92 return (vect->type == EXPR_UNKNOWN);
93}
94
95/*
H. Peter Anvin6867acc2007-10-10 14:58:45 -070096 * Return true if the argument contains nothing but an `unknown'
H. Peter Anvin87f252a2007-09-19 21:40:37 -070097 * part.
98 */
99int is_just_unknown(expr * vect)
100{
101 while (vect->type && !vect->value)
102 vect++;
103 return (vect->type == EXPR_UNKNOWN);
104}
105
106/*
107 * Return the scalar part of a relocatable vector. (Including
108 * simple scalar vectors - those qualify as relocatable.)
109 */
110int64_t reloc_value(expr * vect)
111{
112 while (vect->type && !vect->value)
113 vect++;
114 if (!vect->type)
115 return 0;
116 if (vect->type == EXPR_SIMPLE)
117 return vect->value;
118 else
119 return 0;
120}
121
122/*
123 * Return the segment number of a relocatable vector, or NO_SEG for
124 * simple scalars.
125 */
126int32_t reloc_seg(expr * vect)
127{
128 while (vect->type && (vect->type == EXPR_WRT || !vect->value))
129 vect++;
130 if (vect->type == EXPR_SIMPLE) {
131 do {
132 vect++;
133 } while (vect->type && (vect->type == EXPR_WRT || !vect->value));
134 }
135 if (!vect->type)
136 return NO_SEG;
137 else
138 return vect->type - EXPR_SEGBASE;
139}
140
141/*
142 * Return the WRT segment number of a relocatable vector, or NO_SEG
143 * if no WRT part is present.
144 */
145int32_t reloc_wrt(expr * vect)
146{
147 while (vect->type && vect->type < EXPR_WRT)
148 vect++;
149 if (vect->type == EXPR_WRT) {
150 return vect->value;
151 } else
152 return NO_SEG;
153}