* do not warn on lea e/rsp with negative address offset, part of #40113

+ tests
This commit is contained in:
florian 2023-01-15 23:05:32 +01:00
parent fdea66d217
commit 8b08486fa1
4 changed files with 44 additions and 7 deletions

View File

@ -91,6 +91,8 @@ type
{$endif aarch64} {$endif aarch64}
end; end;
TInstruction = class;
TOperand = class TOperand = class
opr : TOprRec; opr : TOprRec;
typesize : byte; typesize : byte;
@ -109,7 +111,7 @@ type
Function SetupSelf:boolean; Function SetupSelf:boolean;
Function SetupOldEBP:boolean; Function SetupOldEBP:boolean;
Function SetupVar(const s:string;GetOffset : boolean): Boolean; Function SetupVar(const s:string;GetOffset : boolean): Boolean;
Function CheckOperand: boolean; virtual; function CheckOperand(ins : TInstruction): boolean; virtual;
Procedure InitRef; Procedure InitRef;
Procedure InitRefConvertLocal; Procedure InitRefConvertLocal;
protected protected
@ -1229,7 +1231,7 @@ begin
Fillchar(opr.ref,sizeof(treference),0); Fillchar(opr.ref,sizeof(treference),0);
end; end;
Function TOperand.CheckOperand: boolean; Function TOperand.CheckOperand(ins : TInstruction): boolean;
{*********************************************************************} {*********************************************************************}
{ Description: This routine checks if the operand is of } { Description: This routine checks if the operand is of }
{ valid, and returns false if it isn't. Does nothing by default. } { valid, and returns false if it isn't. Does nothing by default. }
@ -1274,7 +1276,7 @@ end;
i : longint; i : longint;
begin begin
for i:=1 to Ops do for i:=1 to Ops do
operands[i].CheckOperand; operands[i].CheckOperand(self);
ai:=taicpu.op_none(opcode); ai:=taicpu.op_none(opcode);
ai.fileinfo:=filepos; ai.fileinfo:=filepos;

View File

@ -46,7 +46,7 @@ type
vbcst : byte; vbcst : byte;
Procedure SetSize(_size:longint;force:boolean);override; Procedure SetSize(_size:longint;force:boolean);override;
Procedure SetCorrectSize(opcode:tasmop);override; Procedure SetCorrectSize(opcode:tasmop);override;
Function CheckOperand: boolean; override; Function CheckOperand(ins : TInstruction): boolean; override;
{ handles the @Code symbol } { handles the @Code symbol }
Procedure SetupCode; Procedure SetupCode;
{ handles the @Data symbol } { handles the @Data symbol }
@ -258,7 +258,7 @@ begin
end; end;
end; end;
Function Tx86Operand.CheckOperand: boolean; Function Tx86Operand.CheckOperand(ins : TInstruction): boolean;
var var
ErrorRefStr: string; ErrorRefStr: string;
begin begin
@ -330,7 +330,8 @@ begin
end; end;
message1(asmr_w_direct_ebp_neg_offset,ErrorRefStr); message1(asmr_w_direct_ebp_neg_offset,ErrorRefStr);
end end
else if (getsupreg(opr.ref.base)=RS_ESP) and (getsubreg(opr.ref.base)<>R_SUBW) and (opr.ref.offset<0) then else if ((ins.opcode<>A_LEA) and (getsupreg(opr.ref.base)=RS_ESP) and (getsubreg(opr.ref.base)<>R_SUBW) and (opr.ref.offset<0)) or
((ins.opcode=A_LEA) and (getsupreg(ins.operands[2].opr.reg)<>RS_ESP) and (getsupreg(opr.ref.base)=RS_ESP) and (getsubreg(opr.ref.base)<>R_SUBW) and (opr.ref.offset<0)) then
begin begin
if current_settings.asmmode in asmmodes_x86_intel then if current_settings.asmmode in asmmodes_x86_intel then
begin begin
@ -1837,7 +1838,7 @@ begin
ai:=nil; ai:=nil;
for i:=1 to Ops do for i:=1 to Ops do
if not operands[i].CheckOperand then if not operands[i].CheckOperand(self) then
exit; exit;
{ Get Opsize } { Get Opsize }

17
tests/webtbf/tw40113b.pp Normal file
View File

@ -0,0 +1,17 @@
{ %cpu=x86_64 }
{ %opt=-Sew }
{ %fail }
{$asmmode intel}
begin
asm
lea rax, [rsp-32] // (1)
lea rax, @table[rip]
lea rsp, [rsp+32]
jmp @next
db 0, 1, 2, 3, 4, 5, 6, 7
@table:
db 8, 9, 10
@next:
end ['rax', 'xmm0'];
end.

17
tests/webtbs/tw40113a.pp Normal file
View File

@ -0,0 +1,17 @@
{ %cpu=x86_64 }
{ %opt=-Sew }
{ %norun }
{$asmmode intel}
begin
asm
lea rsp, [rsp-32] // (1)
lea rax, @table[rip]
lea rsp, [rsp+32]
jmp @next
db 0, 1, 2, 3, 4, 5, 6, 7
@table:
db 8, 9, 10
@next:
end ['rax', 'xmm0'];
end.