mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-07 17:46:58 +08:00
New opcode for 32->64 bit sign-extended immediate with warning
Add a new opcode for 32->64 bit sign-extended immediate, with warning on the number not matching. This unfortunately calls for an audit of all the \4[0123] opcodes, if they should be replaced by \25[4567]. This only replaces one instruction (MOV reg64,imm32); other instructions need to be considered. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
f70fce6cc9
commit
588df78b0d
22
assemble.c
22
assemble.c
@ -56,6 +56,7 @@
|
||||
* \250..\253 - same as \150..\153, except warn if the 64-bit operand
|
||||
* is not equal to the truncated and sign-extended 32-bit
|
||||
* operand; used for 32-bit immediates in 64-bit mode.
|
||||
* \254..\257 - a signed 32-bit operand to be extended to 64 bits.
|
||||
* \260..\263 - this instruction uses VEX rather than REX, with the
|
||||
* V field taken from operand 0..3.
|
||||
* \270 - this instruction uses VEX rather than REX, with the
|
||||
@ -953,6 +954,12 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
|
||||
case 0253:
|
||||
length += is_sbyte32(opx) ? 1 : 4;
|
||||
break;
|
||||
case 0254:
|
||||
case 0255:
|
||||
case 0256:
|
||||
case 0257:
|
||||
length += 4;
|
||||
break;
|
||||
case 0260:
|
||||
case 0261:
|
||||
case 0262:
|
||||
@ -1592,6 +1599,21 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
}
|
||||
break;
|
||||
|
||||
case 0254:
|
||||
case 0255:
|
||||
case 0256:
|
||||
case 0257:
|
||||
data = opx->offset;
|
||||
if (opx->wrt == NO_SEG && opx->segment == NO_SEG &&
|
||||
(int32_t)data != (int64_t)data) {
|
||||
errfunc(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV,
|
||||
"signed dword immediate exceeds bounds");
|
||||
}
|
||||
out(offset, segment, &data, OUT_ADDRESS, 4,
|
||||
opx->segment, opx->wrt);
|
||||
offset += 4;
|
||||
break;
|
||||
|
||||
case 0260:
|
||||
case 0261:
|
||||
case 0262:
|
||||
|
1
disasm.c
1
disasm.c
@ -513,6 +513,7 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
break;
|
||||
|
||||
case4(040):
|
||||
case4(0254):
|
||||
opx->offset = getu32(data);
|
||||
data += 4;
|
||||
break;
|
||||
|
@ -768,7 +768,7 @@ MOV reg8,imm \10\xB0\21 8086,SM
|
||||
MOV reg16,imm \320\10\xB8\31 8086,SM
|
||||
MOV reg32,imm \321\10\xB8\41 386,SM
|
||||
MOV reg64,imm \324\10\xB8\55 X64,SM
|
||||
MOV reg64,imm32 \324\1\xC7\200\41 X64
|
||||
MOV reg64,imm32 \324\1\xC7\200\255 X64
|
||||
MOV rm8,imm \1\xC6\200\21 8086,SM
|
||||
MOV rm16,imm \320\1\xC7\200\31 8086,SM
|
||||
MOV rm32,imm \321\1\xC7\200\41 386,SM
|
||||
|
4
insns.pl
4
insns.pl
@ -658,7 +658,7 @@ sub byte_code_compile($) {
|
||||
# This allows us to match the AMD documentation and still
|
||||
# do the right thing.
|
||||
unshift(@codes, 0160+$oppos{'d'}+($oc0 ? 4 : 0));
|
||||
} elsif ($op =~ /^(ib\,s|ib|ib\,w|iw|iwd|id|iwdq|rel|rel8|rel16|rel32|iq|seg|ibw|ibd|ibd,s)$/) {
|
||||
} elsif ($op =~ /^(ib\,s|ib|ibx|ib\,w|iw|iwd|id|idx|iwdq|rel|rel8|rel16|rel32|iq|seg|ibw|ibd|ibd,s)$/) {
|
||||
if (!defined($oppos{'i'})) {
|
||||
die "$fname: $line: $op without 'i' operand\n";
|
||||
}
|
||||
@ -676,6 +676,8 @@ sub byte_code_compile($) {
|
||||
push(@codes, 034+$oppos{'i'});
|
||||
} elsif ($op eq 'id') { # imm32
|
||||
push(@codes, 040+$oppos{'i'});
|
||||
} elsif ($op eq 'idx') { # imm32 extended to 64 bits
|
||||
push(@codes, 0254+$oppos{'i'});
|
||||
} elsif ($op eq 'iwdq') { # imm16/32/64, depending on opsize
|
||||
push(@codes, 044+$oppos{'i'});
|
||||
} elsif ($op eq 'rel8') {
|
||||
|
@ -72,7 +72,7 @@
|
||||
mov rax,7fffffffh
|
||||
mov rax,80000000h
|
||||
%if WARN
|
||||
mov rax,dword 80000000h ; XXX - missing
|
||||
mov rax,dword 80000000h
|
||||
%endif
|
||||
add rcx,0FFFFh
|
||||
%if WARN
|
||||
|
Loading…
Reference in New Issue
Block a user