blob: 7c24cc00c7d54d45078cd12128a2430970e395d8 [file] [log] [blame]
H. Peter Anvin9e6747c2009-06-28 17:13:04 -07001/* ----------------------------------------------------------------------- *
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +03002 *
H. Peter Anvin (Intel)f397a342020-06-30 10:36:46 -07003 * Copyright 1996-2020 The NASM Authors - All Rights Reserved
H. Peter Anvin9e6747c2009-06-28 17:13:04 -07004 * See the file AUTHORS included with the NASM distribution for
5 * the specific copyright holders.
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00006 *
H. Peter Anvin9e6747c2009-06-28 17:13:04 -07007 * 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.
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +030017 *
H. Peter Anvin9e6747c2009-06-28 17:13:04 -070018 * 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 * parser.c source line parser for the Netwide Assembler
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000036 */
37
H. Peter Anvinfe501952007-10-02 21:53:51 -070038#include "compiler.h"
39
H. Peter Anvinc2f3f262018-12-27 12:37:25 -080040#include "nctype.h"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000041
42#include "nasm.h"
H. Peter Anvin24cfef42002-09-12 16:34:06 +000043#include "insns.h"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000044#include "nasmlib.h"
H. Peter Anvinb20bc732017-03-07 19:23:03 -080045#include "error.h"
H. Peter Anvin74cc5e52007-08-30 22:35:34 +000046#include "stdscan.h"
H. Peter Anvin00444ae2009-07-18 18:49:55 -070047#include "eval.h"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000048#include "parser.h"
H. Peter Anvin (Intel)6e9554f2020-06-14 23:21:44 -070049#include "floats.h"
H. Peter Anvinb20bc732017-03-07 19:23:03 -080050#include "assemble.h"
H. Peter Anvina4835d42008-05-20 14:21:29 -070051#include "tables.h"
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000052
H. Peter Anvind0e365d2002-05-26 18:19:19 +000053
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -070054static int end_expression_next(void);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000055
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000056static struct tokenval tokval;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +000057
Cyrill Gorcunov18914e62011-11-12 11:41:51 +040058static int prefix_slot(int prefix)
H. Peter Anvinde4b89b2007-10-01 15:41:25 -070059{
60 switch (prefix) {
H. Peter Anvinc2acf7b2009-02-21 18:22:56 -080061 case P_WAIT:
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +030062 return PPS_WAIT;
H. Peter Anvinde4b89b2007-10-01 15:41:25 -070063 case R_CS:
64 case R_DS:
65 case R_SS:
66 case R_ES:
67 case R_FS:
68 case R_GS:
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +030069 return PPS_SEG;
H. Peter Anvinde4b89b2007-10-01 15:41:25 -070070 case P_LOCK:
H. Peter Anvin10da41e2012-02-24 20:57:04 -080071 return PPS_LOCK;
H. Peter Anvinde4b89b2007-10-01 15:41:25 -070072 case P_REP:
73 case P_REPE:
74 case P_REPZ:
75 case P_REPNE:
76 case P_REPNZ:
H. Peter Anvin4ecd5d72012-02-24 21:51:46 -080077 case P_XACQUIRE:
78 case P_XRELEASE:
Jin Kyu Song03041092013-10-15 19:38:51 -070079 case P_BND:
Jin Kyu Songb287ff02013-12-04 20:05:55 -080080 case P_NOBND:
H. Peter Anvin10da41e2012-02-24 20:57:04 -080081 return PPS_REP;
H. Peter Anvinde4b89b2007-10-01 15:41:25 -070082 case P_O16:
83 case P_O32:
84 case P_O64:
85 case P_OSP:
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +030086 return PPS_OSIZE;
H. Peter Anvinde4b89b2007-10-01 15:41:25 -070087 case P_A16:
88 case P_A32:
89 case P_A64:
90 case P_ASP:
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +030091 return PPS_ASIZE;
Jin Kyu Song945b1b82013-10-25 19:29:53 -070092 case P_EVEX:
H. Peter Anvin621a69a2013-11-28 12:11:24 -080093 case P_VEX3:
94 case P_VEX2:
95 return PPS_VEX;
H. Peter Anvinde4b89b2007-10-01 15:41:25 -070096 default:
H. Peter Anvinc5136902018-06-15 18:20:17 -070097 nasm_panic("Invalid value %d passed to prefix_slot()", prefix);
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +030098 return -1;
H. Peter Anvinde4b89b2007-10-01 15:41:25 -070099 }
100}
101
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700102static void process_size_override(insn *result, operand *op)
H. Peter Anvinde4b89b2007-10-01 15:41:25 -0700103{
104 if (tasm_compatible_mode) {
H. Peter Anvin09dff8b2017-03-01 01:01:37 -0800105 switch (tokval.t_integer) {
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300106 /* For TASM compatibility a size override inside the
107 * brackets changes the size of the operand, not the
108 * address type of the operand as it does in standard
109 * NASM syntax. Hence:
110 *
111 * mov eax,[DWORD val]
112 *
113 * is valid syntax in TASM compatibility mode. Note that
114 * you lose the ability to override the default address
115 * type for the instruction, but we never use anything
116 * but 32-bit flat model addressing in our code.
117 */
118 case S_BYTE:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700119 op->type |= BITS8;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300120 break;
121 case S_WORD:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700122 op->type |= BITS16;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300123 break;
124 case S_DWORD:
125 case S_LONG:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700126 op->type |= BITS32;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300127 break;
128 case S_QWORD:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700129 op->type |= BITS64;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300130 break;
131 case S_TWORD:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700132 op->type |= BITS80;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300133 break;
134 case S_OWORD:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700135 op->type |= BITS128;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300136 break;
137 default:
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300138 nasm_nonfatal("invalid operand size specification");
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300139 break;
140 }
H. Peter Anvinde4b89b2007-10-01 15:41:25 -0700141 } else {
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300142 /* Standard NASM compatible syntax */
H. Peter Anvin09dff8b2017-03-01 01:01:37 -0800143 switch (tokval.t_integer) {
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300144 case S_NOSPLIT:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700145 op->eaflags |= EAF_TIMESTWO;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300146 break;
147 case S_REL:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700148 op->eaflags |= EAF_REL;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300149 break;
150 case S_ABS:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700151 op->eaflags |= EAF_ABS;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300152 break;
153 case S_BYTE:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700154 op->disp_size = 8;
155 op->eaflags |= EAF_BYTEOFFS;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300156 break;
157 case P_A16:
158 case P_A32:
159 case P_A64:
160 if (result->prefixes[PPS_ASIZE] &&
161 result->prefixes[PPS_ASIZE] != tokval.t_integer)
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300162 nasm_nonfatal("conflicting address size specifications");
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300163 else
164 result->prefixes[PPS_ASIZE] = tokval.t_integer;
165 break;
166 case S_WORD:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700167 op->disp_size = 16;
168 op->eaflags |= EAF_WORDOFFS;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300169 break;
170 case S_DWORD:
171 case S_LONG:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700172 op->disp_size = 32;
173 op->eaflags |= EAF_WORDOFFS;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300174 break;
175 case S_QWORD:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700176 op->disp_size = 64;
177 op->eaflags |= EAF_WORDOFFS;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300178 break;
179 default:
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300180 nasm_nonfatal("invalid size specification in"
181 " effective address");
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300182 break;
183 }
H. Peter Anvinde4b89b2007-10-01 15:41:25 -0700184 }
185}
186
Jin Kyu Song72018a22013-08-05 20:46:18 -0700187/*
H. Peter Anvin8e37ff42017-04-02 18:38:58 -0700188 * Brace decorators are are parsed here. opmask and zeroing
189 * decorators can be placed in any order. e.g. zmm1 {k2}{z} or zmm2
190 * {z}{k3} decorator(s) are placed at the end of an operand.
Jin Kyu Song72018a22013-08-05 20:46:18 -0700191 */
192static bool parse_braces(decoflags_t *decoflags)
193{
H. Peter Anvin8e37ff42017-04-02 18:38:58 -0700194 int i, j;
Jin Kyu Song72018a22013-08-05 20:46:18 -0700195
196 i = tokval.t_type;
H. Peter Anvin8e37ff42017-04-02 18:38:58 -0700197
198 while (true) {
199 switch (i) {
200 case TOKEN_OPMASK:
Jin Kyu Song72018a22013-08-05 20:46:18 -0700201 if (*decoflags & OPMASK_MASK) {
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300202 nasm_nonfatal("opmask k%"PRIu64" is already set",
203 *decoflags & OPMASK_MASK);
Jin Kyu Song72018a22013-08-05 20:46:18 -0700204 *decoflags &= ~OPMASK_MASK;
205 }
206 *decoflags |= VAL_OPMASK(nasm_regvals[tokval.t_integer]);
H. Peter Anvin8e37ff42017-04-02 18:38:58 -0700207 break;
208 case TOKEN_DECORATOR:
209 j = tokval.t_integer;
210 switch (j) {
Jin Kyu Song72018a22013-08-05 20:46:18 -0700211 case BRC_Z:
H. Peter Anvin8e37ff42017-04-02 18:38:58 -0700212 *decoflags |= Z_MASK;
213 break;
214 case BRC_1TO2:
215 case BRC_1TO4:
216 case BRC_1TO8:
217 case BRC_1TO16:
218 *decoflags |= BRDCAST_MASK | VAL_BRNUM(j - BRC_1TO2);
Jin Kyu Song72018a22013-08-05 20:46:18 -0700219 break;
Jin Kyu Songcc1dc9d2013-08-15 19:01:25 -0700220 default:
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300221 nasm_nonfatal("{%s} is not an expected decorator",
222 tokval.t_charptr);
Jin Kyu Songcc1dc9d2013-08-15 19:01:25 -0700223 break;
Jin Kyu Song72018a22013-08-05 20:46:18 -0700224 }
Jin Kyu Song72018a22013-08-05 20:46:18 -0700225 break;
H. Peter Anvin8e37ff42017-04-02 18:38:58 -0700226 case ',':
227 case TOKEN_EOS:
228 return false;
229 default:
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300230 nasm_nonfatal("only a series of valid decorators expected");
H. Peter Anvin8e37ff42017-04-02 18:38:58 -0700231 return true;
Jin Kyu Song72018a22013-08-05 20:46:18 -0700232 }
233 i = stdscan(NULL, &tokval);
H. Peter Anvin8e37ff42017-04-02 18:38:58 -0700234 }
Jin Kyu Song72018a22013-08-05 20:46:18 -0700235}
236
H. Peter Anvin (Intel)65ab3ab2020-06-30 10:14:21 -0700237static inline unused
238const expr *next_expr(const expr *e, const expr **next_list)
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700239{
240 e++;
241 if (!e->type) {
242 if (next_list) {
243 e = *next_list;
244 *next_list = NULL;
245 } else {
246 e = NULL;
247 }
248 }
249 return e;
250}
251
252static inline void init_operand(operand *op)
253{
254 memset(op, 0, sizeof *op);
255
256 op->basereg = -1;
257 op->indexreg = -1;
258 op->segment = NO_SEG;
259 op->wrt = NO_SEG;
260}
261
H. Peter Anvin9148fb52013-09-27 16:39:16 -0700262static int parse_mref(operand *op, const expr *e)
H. Peter Anvin9f4706f2013-09-26 17:28:39 -0700263{
264 int b, i, s; /* basereg, indexreg, scale */
265 int64_t o; /* offset */
266
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700267 b = op->basereg;
268 i = op->indexreg;
269 s = op->scale;
270 o = op->offset;
H. Peter Anvin9f4706f2013-09-26 17:28:39 -0700271
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700272 for (; e->type; e++) {
273 if (e->type <= EXPR_REG_END) {
274 bool is_gpr = is_class(REG_GPR,nasm_reg_flags[e->type]);
H. Peter Anvin9f4706f2013-09-26 17:28:39 -0700275
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700276 if (is_gpr && e->value == 1 && b == -1) {
277 /* It can be basereg */
278 b = e->type;
279 } else if (i == -1) {
280 /* Must be index register */
281 i = e->type;
282 s = e->value;
H. Peter Anvin9f4706f2013-09-26 17:28:39 -0700283 } else {
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700284 if (b == -1)
285 nasm_nonfatal("invalid effective address: two index registers");
286 else if (!is_gpr)
287 nasm_nonfatal("invalid effective address: impossible register");
288 else
289 nasm_nonfatal("invalid effective address: too many registers");
290 return -1;
H. Peter Anvin9f4706f2013-09-26 17:28:39 -0700291 }
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700292 } else if (e->type == EXPR_UNKNOWN) {
293 op->opflags |= OPFLAG_UNKNOWN;
294 } else if (e->type == EXPR_SIMPLE) {
295 o += e->value;
296 } else if (e->type == EXPR_WRT) {
297 op->wrt = e->value;
298 } else if (e->type >= EXPR_SEGBASE) {
299 if (e->value == 1) {
300 if (op->segment != NO_SEG) {
301 nasm_nonfatal("invalid effective address: multiple base segments");
302 return -1;
303 }
304 op->segment = e->type - EXPR_SEGBASE;
305 } else if (e->value == -1 &&
306 e->type == location.segment + EXPR_SEGBASE &&
307 !(op->opflags & OPFLAG_RELATIVE)) {
308 op->opflags |= OPFLAG_RELATIVE;
309 } else {
310 nasm_nonfatal("invalid effective address: impossible segment base multiplier");
311 return -1;
312 }
313 } else {
314 nasm_nonfatal("invalid effective address: bad subexpression type");
315 return -1;
H. Peter Anvin9f4706f2013-09-26 17:28:39 -0700316 }
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700317 }
H. Peter Anvin9f4706f2013-09-26 17:28:39 -0700318
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700319 op->basereg = b;
H. Peter Anvin9148fb52013-09-27 16:39:16 -0700320 op->indexreg = i;
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700321 op->scale = s;
322 op->offset = o;
H. Peter Anvin9148fb52013-09-27 16:39:16 -0700323 return 0;
324}
325
326static void mref_set_optype(operand *op)
327{
328 int b = op->basereg;
329 int i = op->indexreg;
330 int s = op->scale;
331
H. Peter Anvin9f4706f2013-09-26 17:28:39 -0700332 /* It is memory, but it can match any r/m operand */
333 op->type |= MEMORY_ANY;
334
335 if (b == -1 && (i == -1 || s == 0)) {
336 int is_rel = globalbits == 64 &&
337 !(op->eaflags & EAF_ABS) &&
338 ((globalrel &&
339 !(op->eaflags & EAF_FSGS)) ||
340 (op->eaflags & EAF_REL));
341
342 op->type |= is_rel ? IP_REL : MEM_OFFS;
343 }
344
345 if (i != -1) {
346 opflags_t iclass = nasm_reg_flags[i];
347
348 if (is_class(XMMREG,iclass))
349 op->type |= XMEM;
350 else if (is_class(YMMREG,iclass))
351 op->type |= YMEM;
352 else if (is_class(ZMMREG,iclass))
353 op->type |= ZMEM;
354 }
H. Peter Anvin9f4706f2013-09-26 17:28:39 -0700355}
356
H. Peter Anvin472a7c12016-10-31 08:44:25 -0700357/*
358 * Convert an expression vector returned from evaluate() into an
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700359 * extop structure. Return zero on success. Note that the eop
360 * already has dup and elem set, so we can't clear it here.
H. Peter Anvin472a7c12016-10-31 08:44:25 -0700361 */
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700362static int value_to_extop(expr *vect, extop *eop, int32_t myseg)
H. Peter Anvin472a7c12016-10-31 08:44:25 -0700363{
364 eop->type = EOT_DB_NUMBER;
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700365 eop->val.num.offset = 0;
366 eop->val.num.segment = eop->val.num.wrt = NO_SEG;
367 eop->val.num.relative = false;
H. Peter Anvin472a7c12016-10-31 08:44:25 -0700368
369 for (; vect->type; vect++) {
370 if (!vect->value) /* zero term, safe to ignore */
371 continue;
372
Cyrill Gorcunovfd610f22016-11-28 23:57:08 +0300373 if (vect->type <= EXPR_REG_END) /* false if a register is present */
H. Peter Anvin472a7c12016-10-31 08:44:25 -0700374 return -1;
375
376 if (vect->type == EXPR_UNKNOWN) /* something we can't resolve yet */
377 return 0;
378
379 if (vect->type == EXPR_SIMPLE) {
380 /* Simple number expression */
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700381 eop->val.num.offset += vect->value;
H. Peter Anvin472a7c12016-10-31 08:44:25 -0700382 continue;
383 }
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700384 if (eop->val.num.wrt == NO_SEG && !eop->val.num.relative &&
385 vect->type == EXPR_WRT) {
H. Peter Anvin472a7c12016-10-31 08:44:25 -0700386 /* WRT term */
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700387 eop->val.num.wrt = vect->value;
H. Peter Anvin472a7c12016-10-31 08:44:25 -0700388 continue;
389 }
390
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700391 if (!eop->val.num.relative &&
H. Peter Anvin472a7c12016-10-31 08:44:25 -0700392 vect->type == EXPR_SEGBASE + myseg && vect->value == -1) {
393 /* Expression of the form: foo - $ */
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700394 eop->val.num.relative = true;
H. Peter Anvin472a7c12016-10-31 08:44:25 -0700395 continue;
396 }
397
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700398 if (eop->val.num.segment == NO_SEG &&
399 vect->type >= EXPR_SEGBASE && vect->value == 1) {
400 eop->val.num.segment = vect->type - EXPR_SEGBASE;
H. Peter Anvin472a7c12016-10-31 08:44:25 -0700401 continue;
402 }
403
404 /* Otherwise, badness */
405 return -1;
406 }
407
408 /* We got to the end and it was all okay */
409 return 0;
410}
411
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700412/*
413 * Parse an extended expression, used by db et al. "elem" is the element
414 * size; initially comes from the specific opcode (e.g. db == 1) but
415 * can be overridden.
416 */
417static int parse_eops(extop **result, bool critical, int elem)
418{
419 extop *eop = NULL, *prev = NULL;
420 extop **tail = result;
421 int sign;
422 int i = tokval.t_type;
423 int oper_num = 0;
424 bool do_subexpr = false;
425
426 *tail = NULL;
427
428 /* End of string is obvious; ) ends a sub-expression list e.g. DUP */
429 for (i = tokval.t_type; i != TOKEN_EOS; i = stdscan(NULL, &tokval)) {
430 char endparen = ')'; /* Is a right paren the end of list? */
431
432 if (i == ')')
433 break;
434
435 if (!eop) {
436 nasm_new(eop);
437 eop->dup = 1;
438 eop->elem = elem;
439 do_subexpr = false;
440 }
441 sign = +1;
442
443 /*
444 * end_expression_next() here is to distinguish this from
445 * a string used as part of an expression...
446 */
447 if (i == TOKEN_QMARK) {
448 eop->type = EOT_DB_RESERVE;
449 } else if (do_subexpr && i == '(') {
450 extop *subexpr;
451
452 stdscan(NULL, &tokval); /* Skip paren */
453 if (parse_eops(&eop->val.subexpr, critical, eop->elem) < 0)
454 goto fail;
455
456 subexpr = eop->val.subexpr;
457 if (!subexpr) {
458 /* Subexpression is empty */
459 eop->type = EOT_NOTHING;
460 } else if (!subexpr->next) {
461 /* Subexpression is a single element, flatten */
462 eop->val = subexpr->val;
463 eop->type = subexpr->type;
464 eop->dup *= subexpr->dup;
465 nasm_free(subexpr);
466 } else {
467 eop->type = EOT_EXTOP;
468 }
469
470 /* We should have ended on a closing paren */
471 if (tokval.t_type != ')') {
472 nasm_nonfatal("expected `)' after subexpression, got `%s'",
473 i == TOKEN_EOS ?
474 "end of line" : tokval.t_charptr);
475 goto fail;
476 }
477 endparen = 0; /* This time the paren is not the end */
478 } else if (i == '%') {
479 /* %(expression_list) */
480 do_subexpr = true;
481 continue;
482 } else if (i == TOKEN_SIZE) {
483 /* Element size override */
484 eop->elem = tokval.t_inttwo;
485 do_subexpr = true;
486 continue;
487 } else if (i == TOKEN_STR && end_expression_next()) {
488 eop->type = EOT_DB_STRING;
489 eop->val.string.data = tokval.t_charptr;
490 eop->val.string.len = tokval.t_inttwo;
491 } else if (i == TOKEN_STRFUNC) {
492 bool parens = false;
493 const char *funcname = tokval.t_charptr;
494 enum strfunc func = tokval.t_integer;
495
496 i = stdscan(NULL, &tokval);
497 if (i == '(') {
498 parens = true;
499 endparen = 0;
500 i = stdscan(NULL, &tokval);
501 }
502 if (i != TOKEN_STR) {
503 nasm_nonfatal("%s must be followed by a string constant",
504 funcname);
505 eop->type = EOT_NOTHING;
506 } else {
507 eop->type = EOT_DB_STRING_FREE;
508 eop->val.string.len =
509 string_transform(tokval.t_charptr, tokval.t_inttwo,
510 &eop->val.string.data, func);
511 if (eop->val.string.len == (size_t)-1) {
512 nasm_nonfatal("invalid input string to %s", funcname);
513 eop->type = EOT_NOTHING;
514 }
515 }
516 if (parens && i && i != ')') {
517 i = stdscan(NULL, &tokval);
518 if (i != ')')
519 nasm_nonfatal("unterminated %s function", funcname);
520 }
521 } else if (i == '-' || i == '+') {
522 char *save = stdscan_get();
523 struct tokenval tmptok;
524
525 sign = (i == '-') ? -1 : 1;
526 if (stdscan(NULL, &tmptok) != TOKEN_FLOAT) {
527 stdscan_set(save);
528 goto is_expression;
529 } else {
530 tokval = tmptok;
531 goto is_float;
532 }
533 } else if (i == TOKEN_FLOAT) {
534 is_float:
535 eop->type = EOT_DB_FLOAT;
536
537 if (eop->elem > 16) {
538 nasm_nonfatal("no %d-bit floating-point format supported",
539 eop->elem << 3);
540 eop->val.string.len = 0;
541 } else if (eop->elem < 1) {
542 nasm_nonfatal("floating-point constant"
543 " encountered in unknown instruction");
544 /*
545 * fix suggested by Pedro Gimeno... original line was:
546 * eop->type = EOT_NOTHING;
547 */
548 eop->val.string.len = 0;
549 } else {
550 eop->val.string.len = eop->elem;
551
552 eop = nasm_realloc(eop, sizeof(extop) + eop->val.string.len);
553 eop->val.string.data = (char *)eop + sizeof(extop);
554 if (!float_const(tokval.t_charptr, sign,
555 (uint8_t *)eop->val.string.data,
556 eop->val.string.len))
557 eop->val.string.len = 0;
558 }
559 if (!eop->val.string.len)
560 eop->type = EOT_NOTHING;
561 } else {
562 /* anything else, assume it is an expression */
563 expr *value;
564
565 is_expression:
566 value = evaluate(stdscan, NULL, &tokval, NULL,
567 critical, NULL);
568 i = tokval.t_type;
569 if (!value) /* Error in evaluator */
570 goto fail;
571 if (tokval.t_flag & TFLAG_DUP) {
572 /* Expression followed by DUP */
573 if (!is_simple(value)) {
574 nasm_nonfatal("non-constant argument supplied to DUP");
575 goto fail;
576 } else if (value->value < 0) {
577 nasm_nonfatal("negative argument supplied to DUP");
578 goto fail;
579 }
580 eop->dup *= (size_t)value->value;
581 do_subexpr = true;
582 continue;
583 }
584 if (value_to_extop(value, eop, location.segment)) {
585 nasm_nonfatal("expression is not simple or relocatable");
586 }
587 }
588
589 if (eop->dup == 0 || eop->type == EOT_NOTHING) {
590 nasm_free(eop);
591 } else if (eop->type == EOT_DB_RESERVE &&
592 prev && prev->type == EOT_DB_RESERVE &&
593 prev->elem == eop->elem) {
594 /* Coalesce multiple EOT_DB_RESERVE */
595 prev->dup += eop->dup;
596 nasm_free(eop);
597 } else {
598 /* Add this eop to the end of the chain */
599 prev = eop;
600 *tail = eop;
601 tail = &eop->next;
602 }
603
604 oper_num++;
605 eop = NULL; /* Done with this operand */
606
607 /*
608 * We're about to call stdscan(), which will eat the
609 * comma that we're currently sitting on between
610 * arguments. However, we'd better check first that it
611 * _is_ a comma.
612 */
613 if (i == TOKEN_EOS || i == endparen) /* Already at end? */
614 break;
615 if (i != ',') {
616 i = stdscan(NULL, &tokval); /* eat the comma or final paren */
617 if (i == TOKEN_EOS || i == ')') /* got end of expression */
618 break;
619 if (i != ',') {
620 nasm_nonfatal("comma expected after operand");
621 goto fail;
622 }
623 }
624 }
625
626 return oper_num;
627
628fail:
629 if (eop)
630 nasm_free(eop);
631 return -1;
632}
633
H. Peter Anvin (Intel)e55d03d2018-12-18 11:12:46 -0800634insn *parse_line(char *buffer, insn *result)
H. Peter Anvineba20a72002-04-30 20:53:55 +0000635{
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +0400636 bool insn_is_label = false;
637 struct eval_hints hints;
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700638 int opnum;
H. Peter Anvin (Intel)e55d03d2018-12-18 11:12:46 -0800639 bool critical;
H. Peter Anvin9c987692007-11-04 21:09:32 -0800640 bool first;
H. Peter Anvin552bc2c2009-06-23 11:34:42 -0700641 bool recover;
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700642 bool far_jmp_ok;
Martin Lindhe58f37c12016-11-16 16:43:16 +0100643 int i;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000644
H. Peter Anvin7daa26f2018-06-02 23:48:16 -0700645 nasm_static_assert(P_none == 0);
646
H. Peter Anvin9c987692007-11-04 21:09:32 -0800647restart_parse:
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +0400648 first = true;
649 result->forw_ref = false;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000650
H. Peter Anvin76690a12002-04-30 20:52:49 +0000651 stdscan_reset();
Cyrill Gorcunov917117f2009-10-29 23:09:18 +0300652 stdscan_set(buffer);
H. Peter Anvin76690a12002-04-30 20:52:49 +0000653 i = stdscan(NULL, &tokval);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000654
H. Peter Anvin3e458a82017-05-01 20:28:29 -0700655 memset(result->prefixes, P_none, sizeof(result->prefixes));
656 result->times = 1; /* No TIMES either yet */
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +0400657 result->label = NULL; /* Assume no label */
658 result->eops = NULL; /* must do this, whatever happens */
659 result->operands = 0; /* must initialize this */
Jin Kyu Songe3a06b92013-08-28 19:15:23 -0700660 result->evex_rm = 0; /* Ensure EVEX rounding mode is reset */
661 result->evex_brerop = -1; /* Reset EVEX broadcasting/ER op position */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000662
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +0400663 /* Ignore blank lines */
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700664 if (i == TOKEN_EOS)
665 goto fail;
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +0400666
Cyrill Gorcunov5abbe372011-08-28 18:49:00 +0400667 if (i != TOKEN_ID &&
668 i != TOKEN_INSN &&
669 i != TOKEN_PREFIX &&
670 (i != TOKEN_REG || !IS_SREG(tokval.t_integer))) {
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300671 nasm_nonfatal("label or instruction expected at start of line");
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700672 goto fail;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000673 }
674
H. Peter Anvin9c987692007-11-04 21:09:32 -0800675 if (i == TOKEN_ID || (insn_is_label && i == TOKEN_INSN)) {
676 /* there's a label here */
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300677 first = false;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000678 result->label = tokval.t_charptr;
679 i = stdscan(NULL, &tokval);
680 if (i == ':') { /* skip over the optional colon */
681 i = stdscan(NULL, &tokval);
682 } else if (i == 0) {
H. Peter Anvin (Intel)723ab482018-12-13 21:53:31 -0800683 /*!
H. Peter Anvinfdeb3b02019-06-06 20:53:17 -0700684 *!label-orphan [on] labels alone on lines without trailing `:'
685 *!=orphan-labels
H. Peter Anvin (Intel)723ab482018-12-13 21:53:31 -0800686 *! warns about source lines which contain no instruction but define
687 *! a label without a trailing colon. This is most likely indicative
688 *! of a typo, but is technically correct NASM syntax (see \k{syntax}.)
689 */
H. Peter Anvinfdeb3b02019-06-06 20:53:17 -0700690 nasm_warn(WARN_LABEL_ORPHAN ,
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300691 "label alone on a line without a colon might be in error");
H. Peter Anvine2c80182005-01-15 22:15:51 +0000692 }
693 if (i != TOKEN_INSN || tokval.t_integer != I_EQU) {
694 /*
H. Peter Anvincd7893d2016-02-18 01:25:46 -0800695 * FIXME: location.segment could be NO_SEG, in which case
H. Peter Anvinb20bc732017-03-07 19:23:03 -0800696 * it is possible we should be passing 'absolute.segment'. Look into this.
H. Peter Anvine2c80182005-01-15 22:15:51 +0000697 * Work out whether that is *really* what we should be doing.
698 * Generally fix things. I think this is right as it is, but
699 * am still not certain.
700 */
H. Peter Anvin (Intel)415b6b32018-06-25 14:09:52 -0700701 define_label(result->label,
702 in_absolute ? absolute.segment : location.segment,
H. Peter Anvin98578072018-06-01 18:02:54 -0700703 location.offset, true);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000704 }
H. Peter Anvineba20a72002-04-30 20:53:55 +0000705 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000706
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +0400707 /* Just a label here */
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700708 if (i == TOKEN_EOS)
709 goto fail;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000710
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000711 while (i == TOKEN_PREFIX ||
Cyrill Gorcunov5abbe372011-08-28 18:49:00 +0400712 (i == TOKEN_REG && IS_SREG(tokval.t_integer))) {
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300713 first = false;
H. Peter Anvin9c987692007-11-04 21:09:32 -0800714
H. Peter Anvine2c80182005-01-15 22:15:51 +0000715 /*
716 * Handle special case: the TIMES prefix.
717 */
718 if (i == TOKEN_PREFIX && tokval.t_integer == P_TIMES) {
719 expr *value;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000720
H. Peter Anvine2c80182005-01-15 22:15:51 +0000721 i = stdscan(NULL, &tokval);
H. Peter Anvin (Intel)e55d03d2018-12-18 11:12:46 -0800722 value = evaluate(stdscan, NULL, &tokval, NULL, pass_stable(), NULL);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000723 i = tokval.t_type;
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700724 if (!value) /* Error in evaluator */
725 goto fail;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000726 if (!is_simple(value)) {
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300727 nasm_nonfatal("non-constant argument supplied to TIMES");
H. Peter Anvine2c80182005-01-15 22:15:51 +0000728 result->times = 1L;
729 } else {
730 result->times = value->value;
H. Peter Anvin94ead272017-09-27 15:22:23 -0700731 if (value->value < 0) {
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300732 nasm_nonfatalf(ERR_PASS2, "TIMES value %"PRId64" is negative", value->value);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000733 result->times = 0;
734 }
735 }
736 } else {
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300737 int slot = prefix_slot(tokval.t_integer);
738 if (result->prefixes[slot]) {
Charles Crayne052c0bd2007-10-29 18:24:59 -0700739 if (result->prefixes[slot] == tokval.t_integer)
H. Peter Anvin (Intel)5df6ca72018-12-18 12:25:11 -0800740 nasm_warn(WARN_OTHER, "instruction has redundant prefixes");
Charles Crayne052c0bd2007-10-29 18:24:59 -0700741 else
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300742 nasm_nonfatal("instruction has conflicting prefixes");
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300743 }
744 result->prefixes[slot] = tokval.t_integer;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000745 i = stdscan(NULL, &tokval);
746 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000747 }
748
749 if (i != TOKEN_INSN) {
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300750 int j;
751 enum prefixes pfx;
H. Peter Anvinde4b89b2007-10-01 15:41:25 -0700752
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +0400753 for (j = 0; j < MAXPREFIX; j++) {
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300754 if ((pfx = result->prefixes[j]) != P_none)
755 break;
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +0400756 }
H. Peter Anvincb583b92007-10-28 22:04:42 -0700757
H. Peter Anvinde4b89b2007-10-01 15:41:25 -0700758 if (i == 0 && pfx != P_none) {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000759 /*
760 * Instruction prefixes are present, but no actual
761 * instruction. This is allowed: at this point we
762 * invent a notional instruction of RESB 0.
763 */
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +0400764 result->opcode = I_RESB;
765 result->operands = 1;
H. Peter Anvin1980abf2017-03-31 14:52:03 -0700766 nasm_zero(result->oprs);
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +0400767 result->oprs[0].type = IMMEDIATE;
768 result->oprs[0].offset = 0L;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000769 result->oprs[0].segment = result->oprs[0].wrt = NO_SEG;
770 return result;
771 } else {
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300772 nasm_nonfatal("parser: instruction expected");
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700773 goto fail;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000774 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000775 }
776
777 result->opcode = tokval.t_integer;
778 result->condition = tokval.t_inttwo;
779
780 /*
Charles Crayne2581c862008-09-10 19:21:52 -0700781 * INCBIN cannot be satisfied with incorrectly
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000782 * evaluated operands, since the correct values _must_ be known
783 * on the first pass. Hence, even in pass one, we set the
784 * `critical' flag on calling evaluate(), so that it will bomb
Charles Crayne2581c862008-09-10 19:21:52 -0700785 * out on undefined symbols.
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000786 */
H. Peter Anvin (Intel)e55d03d2018-12-18 11:12:46 -0800787 critical = pass_final() || (result->opcode == I_INCBIN);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000788
H. Peter Anvin3e458a82017-05-01 20:28:29 -0700789 if (opcode_is_db(result->opcode) || result->opcode == I_INCBIN) {
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700790 int oper_num;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000791
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700792 i = stdscan(NULL, &tokval);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000793
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700794 if (first && i == ':') {
795 /* Really a label */
796 insn_is_label = true;
797 goto restart_parse;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000798 }
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700799 first = false;
800 oper_num = parse_eops(&result->eops, critical, db_bytes(result->opcode));
801 if (oper_num < 0)
802 goto fail;
H. Peter Anvind7ed89e2002-04-30 20:52:08 +0000803
H. Peter Anvine2c80182005-01-15 22:15:51 +0000804 if (result->opcode == I_INCBIN) {
805 /*
806 * Correct syntax for INCBIN is that there should be
807 * one string operand, followed by one or two numeric
808 * operands.
809 */
810 if (!result->eops || result->eops->type != EOT_DB_STRING)
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300811 nasm_nonfatal("`incbin' expects a file name");
H. Peter Anvine2c80182005-01-15 22:15:51 +0000812 else if (result->eops->next &&
813 result->eops->next->type != EOT_DB_NUMBER)
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300814 nasm_nonfatal("`incbin': second parameter is"
815 " non-numeric");
H. Peter Anvine2c80182005-01-15 22:15:51 +0000816 else if (result->eops->next && result->eops->next->next &&
817 result->eops->next->next->type != EOT_DB_NUMBER)
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300818 nasm_nonfatal("`incbin': third parameter is"
819 " non-numeric");
H. Peter Anvine2c80182005-01-15 22:15:51 +0000820 else if (result->eops->next && result->eops->next->next &&
821 result->eops->next->next->next)
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300822 nasm_nonfatal("`incbin': more than three parameters");
H. Peter Anvineba20a72002-04-30 20:53:55 +0000823 else
H. Peter Anvine2c80182005-01-15 22:15:51 +0000824 return result;
825 /*
826 * If we reach here, one of the above errors happened.
827 * Throw the instruction away.
828 */
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700829 goto fail;
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700830 } else {
831 /* DB et al */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000832 result->operands = oper_num;
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700833 if (oper_num == 0)
H. Peter Anvin (Intel)f397a342020-06-30 10:36:46 -0700834 /*!
835 *!db-empty [on] no operand for data declaration
836 *! warns about a \c{DB}, \c{DW}, etc declaration
837 *! with no operands, producing no output.
838 *! This is permitted, but often indicative of an error.
839 *! See \k{db}.
840 */
841 nasm_warn(WARN_DB_EMPTY, "no operand for data declaration");
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -0700842 }
H. Peter Anvine2c80182005-01-15 22:15:51 +0000843 return result;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000844 }
845
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +0400846 /*
847 * Now we begin to parse the operands. There may be up to four
848 * of these, separated by commas, and terminated by a zero token.
849 */
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700850 far_jmp_ok = result->opcode == I_JMP || result->opcode == I_CALL;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000851
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700852 for (opnum = 0; opnum < MAX_OPERANDS; opnum++) {
853 operand *op = &result->oprs[opnum];
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300854 expr *value; /* used most of the time */
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700855 bool mref = false; /* is this going to be a memory ref? */
856 int bracket = 0; /* is it a [] mref, or a "naked" mref? */
H. Peter Anvin9148fb52013-09-27 16:39:16 -0700857 bool mib; /* compound (mib) mref? */
H. Peter Anvine2c80182005-01-15 22:15:51 +0000858 int setsize = 0;
Jin Kyu Song72018a22013-08-05 20:46:18 -0700859 decoflags_t brace_flags = 0; /* flags for decorators in braces */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000860
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700861 init_operand(op);
H. Peter Anvineba20a72002-04-30 20:53:55 +0000862
H. Peter Anvine2c80182005-01-15 22:15:51 +0000863 i = stdscan(NULL, &tokval);
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +0400864 if (i == TOKEN_EOS)
H. Peter Anvine2c80182005-01-15 22:15:51 +0000865 break; /* end of operands: get out of here */
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +0300866 else if (first && i == ':') {
867 insn_is_label = true;
868 goto restart_parse;
869 }
870 first = false;
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700871 op->type = 0; /* so far, no override */
H. Peter Anvin11599f42018-12-22 23:09:54 -0800872 /* size specifiers */
873 while (i == TOKEN_SPECIAL || i == TOKEN_SIZE) {
H. Peter Anvin09dff8b2017-03-01 01:01:37 -0800874 switch (tokval.t_integer) {
H. Peter Anvine2c80182005-01-15 22:15:51 +0000875 case S_BYTE:
876 if (!setsize) /* we want to use only the first */
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700877 op->type |= BITS8;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000878 setsize = 1;
879 break;
880 case S_WORD:
881 if (!setsize)
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700882 op->type |= BITS16;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000883 setsize = 1;
884 break;
885 case S_DWORD:
886 case S_LONG:
887 if (!setsize)
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700888 op->type |= BITS32;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000889 setsize = 1;
890 break;
891 case S_QWORD:
892 if (!setsize)
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700893 op->type |= BITS64;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000894 setsize = 1;
895 break;
896 case S_TWORD:
897 if (!setsize)
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700898 op->type |= BITS80;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000899 setsize = 1;
900 break;
H. Peter Anvin41c9f6f2007-09-18 13:01:32 -0700901 case S_OWORD:
902 if (!setsize)
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700903 op->type |= BITS128;
H. Peter Anvin41c9f6f2007-09-18 13:01:32 -0700904 setsize = 1;
905 break;
H. Peter Anvindfb91802008-05-20 11:43:53 -0700906 case S_YWORD:
907 if (!setsize)
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700908 op->type |= BITS256;
H. Peter Anvindfb91802008-05-20 11:43:53 -0700909 setsize = 1;
910 break;
Jin Kyu Songd4760c12013-08-21 19:29:11 -0700911 case S_ZWORD:
912 if (!setsize)
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700913 op->type |= BITS512;
Jin Kyu Songd4760c12013-08-21 19:29:11 -0700914 setsize = 1;
915 break;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000916 case S_TO:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700917 op->type |= TO;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000918 break;
919 case S_STRICT:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700920 op->type |= STRICT;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000921 break;
922 case S_FAR:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700923 op->type |= FAR;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000924 break;
925 case S_NEAR:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700926 op->type |= NEAR;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000927 break;
928 case S_SHORT:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700929 op->type |= SHORT;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000930 break;
931 default:
Cyrill Gorcunova14e6562018-12-01 20:20:50 +0300932 nasm_nonfatal("invalid operand size specification");
H. Peter Anvine2c80182005-01-15 22:15:51 +0000933 }
934 i = stdscan(NULL, &tokval);
935 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000936
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700937 if (i == '[' || i == TOKEN_MASM_PTR || i == '&') {
938 /* memory reference */
H. Peter Anvin6867acc2007-10-10 14:58:45 -0700939 mref = true;
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700940 bracket += (i == '[');
941 i = stdscan(NULL, &tokval);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000942 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +0000943
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700944 mref_more:
945 if (mref) {
946 bool done = false;
947 bool nofw = false;
948
949 while (!done) {
950 switch (i) {
951 case TOKEN_SPECIAL:
952 case TOKEN_SIZE:
953 case TOKEN_PREFIX:
954 process_size_override(result, op);
955 break;
956
957 case '[':
958 bracket++;
959 break;
960
961 case ',':
962 tokval.t_type = TOKEN_NUM;
963 tokval.t_integer = 0;
964 stdscan_set(stdscan_get() - 1); /* rewind the comma */
965 done = nofw = true;
966 break;
967
968 case TOKEN_MASM_FLAT:
969 i = stdscan(NULL, &tokval);
970 if (i != ':') {
971 nasm_nonfatal("unknown use of FLAT in MASM emulation");
972 nofw = true;
973 }
974 done = true;
975 break;
976
977 default:
978 done = nofw = true;
979 break;
980 }
981
982 if (!nofw)
983 i = stdscan(NULL, &tokval);
984 }
985 }
Debbie Wiles63b53f72002-06-04 19:31:24 +0000986
H. Peter Anvine2c80182005-01-15 22:15:51 +0000987 value = evaluate(stdscan, NULL, &tokval,
H. Peter Anvin130736c2016-02-17 20:27:41 -0800988 &op->opflags, critical, &hints);
H. Peter Anvine2c80182005-01-15 22:15:51 +0000989 i = tokval.t_type;
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700990 if (op->opflags & OPFLAG_FORWARD) {
H. Peter Anvin6867acc2007-10-10 14:58:45 -0700991 result->forw_ref = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +0000992 }
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -0700993 if (!value) /* Error in evaluator */
994 goto fail;
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -0700995
996 if (i == '[' && !bracket) {
997 /* displacement[regs] syntax */
998 mref = true;
999 parse_mref(op, value); /* Process what we have so far */
1000 goto mref_more;
1001 }
1002
1003 if (i == ':' && (mref || !far_jmp_ok)) {
1004 /* segment override? */
1005 mref = true;
1006
H. Peter Anvine2c80182005-01-15 22:15:51 +00001007 /*
1008 * Process the segment override.
1009 */
Cyrill Gorcunov5abbe372011-08-28 18:49:00 +04001010 if (value[1].type != 0 ||
1011 value->value != 1 ||
1012 !IS_SREG(value->type))
Cyrill Gorcunova14e6562018-12-01 20:20:50 +03001013 nasm_nonfatal("invalid segment override");
H. Peter Anvinde4b89b2007-10-01 15:41:25 -07001014 else if (result->prefixes[PPS_SEG])
Cyrill Gorcunova14e6562018-12-01 20:20:50 +03001015 nasm_nonfatal("instruction has conflicting segment overrides");
H. Peter Anvin99c4ecd2007-08-28 23:06:00 +00001016 else {
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +03001017 result->prefixes[PPS_SEG] = value->type;
Cyrill Gorcunov5abbe372011-08-28 18:49:00 +04001018 if (IS_FSGS(value->type))
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001019 op->eaflags |= EAF_FSGS;
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +03001020 }
H. Peter Anvin76690a12002-04-30 20:52:49 +00001021
H. Peter Anvine2c80182005-01-15 22:15:51 +00001022 i = stdscan(NULL, &tokval); /* then skip the colon */
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -07001023 goto mref_more;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001024 }
Victor van den Elzen02846d32009-06-23 03:47:07 +02001025
H. Peter Anvin9148fb52013-09-27 16:39:16 -07001026 mib = false;
1027 if (mref && bracket && i == ',') {
1028 /* [seg:base+offset,index*scale] syntax (mib) */
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -07001029 operand o2; /* Index operand */
H. Peter Anvin9148fb52013-09-27 16:39:16 -07001030
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -07001031 if (parse_mref(op, value))
H. Peter Anvin9148fb52013-09-27 16:39:16 -07001032 goto fail;
1033
1034 i = stdscan(NULL, &tokval); /* Eat comma */
1035 value = evaluate(stdscan, NULL, &tokval, &op->opflags,
H. Peter Anvin130736c2016-02-17 20:27:41 -08001036 critical, &hints);
H. Peter Anvin9148fb52013-09-27 16:39:16 -07001037 i = tokval.t_type;
Cyrill Gorcunov5c0b0822014-11-22 18:20:29 +03001038 if (!value)
1039 goto fail;
H. Peter Anvin9148fb52013-09-27 16:39:16 -07001040
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -07001041 init_operand(&o2);
H. Peter Anvin9148fb52013-09-27 16:39:16 -07001042 if (parse_mref(&o2, value))
1043 goto fail;
1044
1045 if (o2.basereg != -1 && o2.indexreg == -1) {
1046 o2.indexreg = o2.basereg;
1047 o2.scale = 1;
1048 o2.basereg = -1;
1049 }
1050
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -07001051 if (op->indexreg != -1 || o2.basereg != -1 || o2.offset != 0 ||
H. Peter Anvin9148fb52013-09-27 16:39:16 -07001052 o2.segment != NO_SEG || o2.wrt != NO_SEG) {
Cyrill Gorcunova14e6562018-12-01 20:20:50 +03001053 nasm_nonfatal("invalid mib expression");
H. Peter Anvin9148fb52013-09-27 16:39:16 -07001054 goto fail;
1055 }
1056
H. Peter Anvin9148fb52013-09-27 16:39:16 -07001057 op->indexreg = o2.indexreg;
1058 op->scale = o2.scale;
H. Peter Anvin9148fb52013-09-27 16:39:16 -07001059
1060 if (op->basereg != -1) {
1061 op->hintbase = op->basereg;
1062 op->hinttype = EAH_MAKEBASE;
1063 } else if (op->indexreg != -1) {
1064 op->hintbase = op->indexreg;
1065 op->hinttype = EAH_NOTBASE;
1066 } else {
1067 op->hintbase = -1;
1068 op->hinttype = EAH_NOHINT;
1069 }
1070
1071 mib = true;
1072 }
1073
H. Peter Anvin552bc2c2009-06-23 11:34:42 -07001074 recover = false;
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -07001075 if (mref) {
1076 if (bracket == 1) {
1077 if (i == ']') {
1078 bracket--;
1079 i = stdscan(NULL, &tokval);
1080 } else {
1081 nasm_nonfatal("expecting ] at end of memory operand");
Victor van den Elzen02846d32009-06-23 03:47:07 +02001082 recover = true;
1083 }
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -07001084 } else if (bracket == 0) {
1085 /* Do nothing */
1086 } else if (bracket > 0) {
1087 nasm_nonfatal("excess brackets in memory operand");
1088 recover = true;
1089 } else if (bracket < 0) {
1090 nasm_nonfatal("unmatched ] in memory operand");
1091 recover = true;
1092 }
1093
1094 if (i == TOKEN_DECORATOR || i == TOKEN_OPMASK) {
1095 /* parse opmask (and zeroing) after an operand */
1096 recover = parse_braces(&brace_flags);
1097 i = tokval.t_type;
1098 }
1099 if (!recover && i != 0 && i != ',') {
1100 nasm_nonfatal("comma, decorator or end of line expected, got %d", i);
1101 recover = true;
Victor van den Elzen02846d32009-06-23 03:47:07 +02001102 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001103 } else { /* immediate operand */
Jin Kyu Song72018a22013-08-05 20:46:18 -07001104 if (i != 0 && i != ',' && i != ':' &&
1105 i != TOKEN_DECORATOR && i != TOKEN_OPMASK) {
Cyrill Gorcunova14e6562018-12-01 20:20:50 +03001106 nasm_nonfatal("comma, colon, decorator or end of "
1107 "line expected after operand");
Victor van den Elzen02846d32009-06-23 03:47:07 +02001108 recover = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001109 } else if (i == ':') {
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001110 op->type |= COLON;
Jin Kyu Song72018a22013-08-05 20:46:18 -07001111 } else if (i == TOKEN_DECORATOR || i == TOKEN_OPMASK) {
1112 /* parse opmask (and zeroing) after an operand */
1113 recover = parse_braces(&brace_flags);
H. Peter Anvine2c80182005-01-15 22:15:51 +00001114 }
1115 }
Victor van den Elzen02846d32009-06-23 03:47:07 +02001116 if (recover) {
1117 do { /* error recovery */
1118 i = stdscan(NULL, &tokval);
1119 } while (i != 0 && i != ',');
1120 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001121
Cyrill Gorcunovcfbcddf2009-10-31 20:05:32 +03001122 /*
1123 * now convert the exprs returned from evaluate()
1124 * into operand descriptions...
1125 */
H. Peter Anvin9148fb52013-09-27 16:39:16 -07001126 op->decoflags |= brace_flags;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001127
H. Peter Anvine2c80182005-01-15 22:15:51 +00001128 if (mref) { /* it's a memory reference */
H. Peter Anvin9148fb52013-09-27 16:39:16 -07001129 /* A mib reference was fully parsed already */
1130 if (!mib) {
1131 if (parse_mref(op, value))
1132 goto fail;
1133 op->hintbase = hints.base;
1134 op->hinttype = hints.type;
1135 }
1136 mref_set_optype(op);
H. Peter Anvin (Intel)89817242019-08-14 15:24:56 -07001137 } else if ((op->type & FAR) && !far_jmp_ok) {
1138 nasm_nonfatal("invalid use of FAR operand specifier");
1139 recover = true;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001140 } else { /* it's not a memory reference */
H. Peter Anvine2c80182005-01-15 22:15:51 +00001141 if (is_just_unknown(value)) { /* it's immediate but unknown */
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001142 op->type |= IMMEDIATE;
1143 op->opflags |= OPFLAG_UNKNOWN;
1144 op->offset = 0; /* don't care */
1145 op->segment = NO_SEG; /* don't care again */
1146 op->wrt = NO_SEG; /* still don't care */
Victor van den Elzen154e5922009-02-25 17:32:00 +01001147
Chang S. Baea5786342018-08-15 23:22:21 +03001148 if(optimizing.level >= 0 && !(op->type & STRICT)) {
Cyrill Gorcunov210c1012009-11-01 10:24:48 +03001149 /* Be optimistic */
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001150 op->type |=
Ben Rudiak-Gould4e8396b2013-03-01 10:28:32 +04001151 UNITY | SBYTEWORD | SBYTEDWORD | UDWORD | SDWORD;
Cyrill Gorcunov210c1012009-11-01 10:24:48 +03001152 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001153 } else if (is_reloc(value)) { /* it's immediate */
H. Peter Anvin87646092017-02-28 17:44:24 -08001154 uint64_t n = reloc_value(value);
1155
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001156 op->type |= IMMEDIATE;
H. Peter Anvin87646092017-02-28 17:44:24 -08001157 op->offset = n;
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001158 op->segment = reloc_seg(value);
1159 op->wrt = reloc_wrt(value);
H. Peter Anvin164d2462017-02-20 02:39:56 -08001160 op->opflags |= is_self_relative(value) ? OPFLAG_RELATIVE : 0;
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +04001161
H. Peter Anvine2c80182005-01-15 22:15:51 +00001162 if (is_simple(value)) {
Ben Rudiak-Gould4e8396b2013-03-01 10:28:32 +04001163 if (n == 1)
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001164 op->type |= UNITY;
Chang S. Baea5786342018-08-15 23:22:21 +03001165 if (optimizing.level >= 0 && !(op->type & STRICT)) {
Ben Rudiak-Gould4e8396b2013-03-01 10:28:32 +04001166 if ((uint32_t) (n + 128) <= 255)
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001167 op->type |= SBYTEDWORD;
Ben Rudiak-Gould4e8396b2013-03-01 10:28:32 +04001168 if ((uint16_t) (n + 128) <= 255)
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001169 op->type |= SBYTEWORD;
H. Peter Anvin87646092017-02-28 17:44:24 -08001170 if (n <= UINT64_C(0xFFFFFFFF))
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001171 op->type |= UDWORD;
H. Peter Anvin87646092017-02-28 17:44:24 -08001172 if (n + UINT64_C(0x80000000) <= UINT64_C(0xFFFFFFFF))
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001173 op->type |= SDWORD;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001174 }
1175 }
H. Peter Anvin164d2462017-02-20 02:39:56 -08001176 } else if (value->type == EXPR_RDSAE) {
Jin Kyu Song72018a22013-08-05 20:46:18 -07001177 /*
1178 * it's not an operand but a rounding or SAE decorator.
1179 * put the decorator information in the (opflag_t) type field
1180 * of previous operand.
1181 */
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001182 opnum--; op--;
Jin Kyu Song72018a22013-08-05 20:46:18 -07001183 switch (value->value) {
1184 case BRC_RN:
1185 case BRC_RU:
1186 case BRC_RD:
1187 case BRC_RZ:
1188 case BRC_SAE:
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001189 op->decoflags |= (value->value == BRC_SAE ? SAE : ER);
Jin Kyu Song72018a22013-08-05 20:46:18 -07001190 result->evex_rm = value->value;
1191 break;
1192 default:
Cyrill Gorcunova14e6562018-12-01 20:20:50 +03001193 nasm_nonfatal("invalid decorator");
Jin Kyu Song72018a22013-08-05 20:46:18 -07001194 break;
1195 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001196 } else { /* it's a register */
Cyrill Gorcunov167917a2012-09-10 00:19:12 +04001197 opflags_t rs;
H. Peter Anvincd26fcc2018-06-25 17:15:08 -07001198 uint64_t regset_size = 0;
H. Peter Anvineba20a72002-04-30 20:53:55 +00001199
H. Peter Anvine2c80182005-01-15 22:15:51 +00001200 if (value->type >= EXPR_SIMPLE || value->value != 1) {
Cyrill Gorcunova14e6562018-12-01 20:20:50 +03001201 nasm_nonfatal("invalid operand type");
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001202 goto fail;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001203 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00001204
H. Peter Anvine2c80182005-01-15 22:15:51 +00001205 /*
H. Peter Anvincd26fcc2018-06-25 17:15:08 -07001206 * We do not allow any kind of expression, except for
1207 * reg+value in which case it is a register set.
H. Peter Anvine2c80182005-01-15 22:15:51 +00001208 */
H. Peter Anvincd26fcc2018-06-25 17:15:08 -07001209 for (i = 1; value[i].type; i++) {
1210 if (!value[i].value)
1211 continue;
1212
1213 switch (value[i].type) {
1214 case EXPR_SIMPLE:
1215 if (!regset_size) {
1216 regset_size = value[i].value + 1;
1217 break;
1218 }
1219 /* fallthrough */
1220 default:
Cyrill Gorcunova14e6562018-12-01 20:20:50 +03001221 nasm_nonfatal("invalid operand type");
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001222 goto fail;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001223 }
H. Peter Anvincd26fcc2018-06-25 17:15:08 -07001224 }
1225
1226 if ((regset_size & (regset_size - 1)) ||
1227 regset_size >= (UINT64_C(1) << REGSET_BITS)) {
Cyrill Gorcunova14e6562018-12-01 20:20:50 +03001228 nasm_nonfatalf(ERR_PASS2, "invalid register set size");
H. Peter Anvincd26fcc2018-06-25 17:15:08 -07001229 regset_size = 0;
1230 }
H. Peter Anvineba20a72002-04-30 20:53:55 +00001231
H. Peter Anvine2c80182005-01-15 22:15:51 +00001232 /* clear overrides, except TO which applies to FPU regs */
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001233 if (op->type & ~TO) {
H. Peter Anvine2c80182005-01-15 22:15:51 +00001234 /*
1235 * we want to produce a warning iff the specified size
1236 * is different from the register size
1237 */
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001238 rs = op->type & SIZE_MASK;
H. Peter Anvincd26fcc2018-06-25 17:15:08 -07001239 } else {
H. Peter Anvin68222142007-11-18 22:18:09 -08001240 rs = 0;
H. Peter Anvincd26fcc2018-06-25 17:15:08 -07001241 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001242
Cyrill Gorcunova28c40d2018-10-13 18:10:26 +03001243 /*
1244 * Make sure we're not out of nasm_reg_flags, still
1245 * probably this should be fixed when we're defining
1246 * the label.
1247 *
1248 * An easy trigger is
1249 *
1250 * e equ 0x80000000:0
1251 * pshufw word e-0
1252 *
1253 */
1254 if (value->type < EXPR_REG_START ||
1255 value->type > EXPR_REG_END) {
Cyrill Gorcunova14e6562018-12-01 20:20:50 +03001256 nasm_nonfatal("invalid operand type");
Cyrill Gorcunova28c40d2018-10-13 18:10:26 +03001257 goto fail;
1258 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001259
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001260 op->type &= TO;
1261 op->type |= REGISTER;
1262 op->type |= nasm_reg_flags[value->type];
H. Peter Anvincd26fcc2018-06-25 17:15:08 -07001263 op->type |= (regset_size >> 1) << REGSET_SHIFT;
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001264 op->decoflags |= brace_flags;
1265 op->basereg = value->type;
H. Peter Anvine2c80182005-01-15 22:15:51 +00001266
H. Peter Anvin (Intel)b1e15f42019-08-09 02:44:46 -07001267 if (rs) {
1268 opflags_t opsize = nasm_reg_flags[value->type] & SIZE_MASK;
1269 if (!opsize) {
1270 op->type |= rs; /* For non-size-specific registers, permit size override */
1271 } else if (opsize != rs) {
1272 /*!
1273 *!regsize [on] register size specification ignored
1274 *!
1275 *! warns about a register with implicit size (such as \c{EAX}, which is always 32 bits)
1276 *! been given an explicit size specification which is inconsistent with the size
1277 *! of the named register, e.g. \c{WORD EAX}. \c{DWORD EAX} or \c{WORD AX} are
1278 *! permitted, and do not trigger this warning. Some registers which \e{do not} imply
1279 *! a specific size, such as \c{K0}, may need this specification unless the instruction
1280 *! itself implies the instruction size:
H. Peter Anvin7ad824b2019-10-03 22:18:35 -07001281 *!-
H. Peter Anvin (Intel)b1e15f42019-08-09 02:44:46 -07001282 *! \c KMOVW K0,[foo] ; Permitted, KMOVW implies 16 bits
1283 *! \c KMOV WORD K0,[foo] ; Permitted, WORD K0 specifies instruction size
1284 *! \c KMOV K0,WORD [foo] ; Permitted, WORD [foo] specifies instruction size
1285 *! \c KMOV K0,[foo] ; Not permitted, instruction size ambiguous
1286 */
1287 nasm_warn(WARN_REGSIZE, "invalid register size specification ignored");
1288 }
1289 }
H. Peter Anvine2c80182005-01-15 22:15:51 +00001290 }
1291 }
Jin Kyu Songe3a06b92013-08-28 19:15:23 -07001292
1293 /* remember the position of operand having broadcasting/ER mode */
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001294 if (op->decoflags & (BRDCAST_MASK | ER | SAE))
1295 result->evex_brerop = opnum;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001296 }
1297
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001298 result->operands = opnum; /* set operand count */
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001299
Cyrill Gorcunovc2509502009-10-14 15:36:45 +04001300 /* clear remaining operands */
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001301 while (opnum < MAX_OPERANDS)
1302 result->oprs[opnum++].type = 0;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001303
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001304 return result;
H. Peter Anvindf0d1ba2013-09-26 17:23:08 -07001305
1306fail:
1307 result->opcode = I_none;
1308 return result;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001309}
1310
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -07001311static int end_expression_next(void)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001312{
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +04001313 struct tokenval tv;
Keith Kaniosa6dfa782007-04-13 16:47:53 +00001314 char *p;
H. Peter Anvin76690a12002-04-30 20:52:49 +00001315 int i;
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001316
Cyrill Gorcunov917117f2009-10-29 23:09:18 +03001317 p = stdscan_get();
H. Peter Anvine2c80182005-01-15 22:15:51 +00001318 i = stdscan(NULL, &tv);
Cyrill Gorcunov917117f2009-10-29 23:09:18 +03001319 stdscan_set(p);
Cyrill Gorcunov447e20c2011-08-28 18:02:31 +04001320
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -07001321 return (i == ',' || i == ';' || i == ')' || !i);
1322}
1323
1324static void free_eops(extop *e)
1325{
1326 extop *next;
1327
1328 while (e) {
1329 next = e->next;
1330 switch (e->type) {
1331 case EOT_EXTOP:
1332 free_eops(e->val.subexpr);
1333 break;
1334
1335 case EOT_DB_STRING_FREE:
1336 nasm_free(e->val.string.data);
1337 break;
1338
1339 default:
1340 break;
1341 }
1342
1343 nasm_free(e);
1344 e = next;
1345 }
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001346}
1347
H. Peter Anvine2c80182005-01-15 22:15:51 +00001348void cleanup_insn(insn * i)
H. Peter Anvineba20a72002-04-30 20:53:55 +00001349{
H. Peter Anvin (Intel)84b852b2019-10-16 14:29:16 -07001350 free_eops(i->eops);
H. Peter Anvinea6e34d2002-04-30 20:51:32 +00001351}