RAA subsystem: use shift instead of divide
[nasm.git] / exprlib.c
blobaf022b892d70289365c270c7355b691aa0f98880
1 /*
2 * exprlib.c
4 * Library routines to manipulate expression data types.
5 */
7 #include "nasm.h"
9 /*
10 * Return true if the argument is a simple scalar. (Or a far-
11 * absolute, which counts.)
13 int is_simple(expr * vect)
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;
30 * Return true if the argument is a simple scalar, _NOT_ a far-
31 * absolute.
33 int is_really_simple(expr * vect)
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;
50 * Return true if the argument is relocatable (i.e. a simple
51 * scalar, plus at most one segment-base, plus possibly a WRT).
53 int is_reloc(expr * vect)
55 while (vect->type && !vect->value) /* skip initial value-0 terms */
56 vect++;
57 if (!vect->type) /* trivially return true if nothing */
58 return 1; /* is present apart from value-0s */
59 if (vect->type < EXPR_SIMPLE) /* false if a register is present */
60 return 0;
61 if (vect->type == EXPR_SIMPLE) { /* skip over a pure number term... */
62 do {
63 vect++;
64 } while (vect->type && !vect->value);
65 if (!vect->type) /* ...returning true if that's all */
66 return 1;
68 if (vect->type == EXPR_WRT) { /* skip over a WRT term... */
69 do {
70 vect++;
71 } while (vect->type && !vect->value);
72 if (!vect->type) /* ...returning true if that's all */
73 return 1;
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);
80 if (!vect->type) /* ...returning true if that's all */
81 return 1;
82 return 0; /* And return false if there's more */
86 * Return true if the argument contains an `unknown' part.
88 int is_unknown(expr * vect)
90 while (vect->type && vect->type < EXPR_UNKNOWN)
91 vect++;
92 return (vect->type == EXPR_UNKNOWN);
96 * Return true if the argument contains nothing but an `unknown'
97 * part.
99 int is_just_unknown(expr * vect)
101 while (vect->type && !vect->value)
102 vect++;
103 return (vect->type == EXPR_UNKNOWN);
107 * Return the scalar part of a relocatable vector. (Including
108 * simple scalar vectors - those qualify as relocatable.)
110 int64_t reloc_value(expr * vect)
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;
123 * Return the segment number of a relocatable vector, or NO_SEG for
124 * simple scalars.
126 int32_t reloc_seg(expr * vect)
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));
135 if (!vect->type)
136 return NO_SEG;
137 else
138 return vect->type - EXPR_SEGBASE;
142 * Return the WRT segment number of a relocatable vector, or NO_SEG
143 * if no WRT part is present.
145 int32_t reloc_wrt(expr * vect)
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;