eval: add support for signed shift operators <<< and >>>

Add support for signed shifts.  The operators are <<< and >>>,
although the former is (inherently) idntical to <<.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2018-06-15 18:37:32 -07:00
parent c51369067c
commit 94adf7d765
3 changed files with 18 additions and 7 deletions

View file

@ -509,7 +509,7 @@ static expr *expr3(int critical)
if (!e)
return NULL;
while (i == TOKEN_SHL || i == TOKEN_SHR) {
while (i == TOKEN_SHL || i == TOKEN_SHR || i == TOKEN_SAR) {
int j = i;
i = scan(scpriv, tokval);
f = expr4(critical);
@ -521,7 +521,7 @@ static expr *expr3(int critical)
" scalar values");
} else if (is_just_unknown(e) || is_just_unknown(f)) {
e = unknown_expr();
} else
} else {
switch (j) {
case TOKEN_SHL:
e = scalarvect(reloc_value(e) << reloc_value(f));
@ -530,7 +530,12 @@ static expr *expr3(int critical)
e = scalarvect(((uint64_t)reloc_value(e)) >>
reloc_value(f));
break;
case TOKEN_SAR:
e = scalarvect(((int64_t)reloc_value(e)) >>
reloc_value(f));
break;
}
}
}
return e;
}

View file

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2016 The NASM Authors - All Rights Reserved
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -305,10 +305,15 @@ int stdscan(void *private_data, struct tokenval *tv)
/* a comment has happened - stay */
return tv->t_type = TOKEN_EOS;
} else if (stdscan_bufptr[0] == '>' && stdscan_bufptr[1] == '>') {
stdscan_bufptr += 2;
return tv->t_type = TOKEN_SHR;
if (stdscan_bufptr[2] == '>') {
stdscan_bufptr += 3;
return tv->t_type = TOKEN_SAR;
} else {
stdscan_bufptr += 2;
return tv->t_type = TOKEN_SHR;
}
} else if (stdscan_bufptr[0] == '<' && stdscan_bufptr[1] == '<') {
stdscan_bufptr += 2;
stdscan_bufptr += stdscan_bufptr[2] == '<' ? 3 : 2;
return tv->t_type = TOKEN_SHL;
} else if (stdscan_bufptr[0] == '/' && stdscan_bufptr[1] == '/') {
stdscan_bufptr += 2;

View file

@ -165,8 +165,9 @@ enum token_type { /* token types, other than chars */
TOKEN_BASE, /* $$ */
TOKEN_SPECIAL, /* BYTE, WORD, DWORD, QWORD, FAR, NEAR, etc */
TOKEN_PREFIX, /* A32, O16, LOCK, REPNZ, TIMES, etc */
TOKEN_SHL, /* << */
TOKEN_SHL, /* << or <<< */
TOKEN_SHR, /* >> */
TOKEN_SAR, /* >>> */
TOKEN_SDIV, /* // */
TOKEN_SMOD, /* %% */
TOKEN_GE, /* >= */