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>
New opcodes to deal with 8-bit immediates which are then sign-extended
to the operand size. These allow us to warn appropriately.
Not sure I'm using these in all the proper places; need audit of all
uses of the \14..\17 opcodes.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
When there is an immediate in the instruction, a RIP-relative offset
may not be relative to the end of the offset itself, since it is
relative to the end of the *instruction*, not the end of the *offset*.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
More tests for immediate warnings, with notes for the ones where we
currently fail to do the right thing.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Using hidden files are rather antisocial, and rather pointless in this
particular context. Change .stdout and .stderr to simply stdout and
stderr.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Do a best attempt at a comprehensive test of the various CVT* SSE
instructions. This includes the bug of BR 2148476.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
There exists a fair bit of code out there which relies on the
optimizer in order to fit inside a predefined envelope. NASM 2.04rc4
breaks this; write a simple test to demonstrate.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Now that there is proper forward reference resolution,
we can get rid of this junk. Wiping the flags also
removed the SBYTEnn flags, causing
cmp eax, a-b
a: nop
b:
to assemble with -Ox like
cmp eax, strict dword -1
This is now fixed.
The testcase illustrates the problem. After "nasm -f obj
alonesym.nasm"
let's look to dump:
======
PUBDEF386(91) recnum:5, offset:0000005bh, len:03f9h, chksum:bbh(bb)
Group: 0, Seg: 1
00020000h - 'sym0000' Type:0
00020004h - 'sym0001' Type:0
....
00020134h - 'sym0077' Type:0
PUBDEF(90) recnum:6, offset:00000457h, len:000ah, chksum:b6h(b6)
Group: 0, Seg: 1
00000138h - 's' Type:2
0000b600h - '' Type:0
======
The problem is while 's' offset is 20138h it is marked as type 90h not
91h. The root cause is located in obj_x():
static ObjRecord *obj_x(ObjRecord * orp, uint32_t val)
{
if (orp->type & 1)
orp->x_size = 32;
if (val > 0xFFFF)
orp = obj_force(orp, 32);
if (orp->x_size == 32)
return (obj_dword(orp, val));
orp->x_size = 16;
return (obj_word(orp, val));
}
It sets up x_size and than writes data. In the testcase data are the
offset and this offset overflows a record. In this case the record is
emitted and its x_size is cleared. Because this is last PUBDEF the new
record with only 's' symbol is emitted also but its x_size is not 32
(it's still zero) so obj_fwrite doesn't switch to 91h type.
The problem seems to be very generic and expected to be occurred on
many other record types as well.
----
And the fix is simple:
if (orp->x_size == 32)
{
ObjRecord * nxt = obj_dword(orp, val);
nxt->x_size = 32; /* x_size is cleared when a record overflows */
return nxt;
}