Browse Source

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

florian 2 years ago
parent
commit
8b08486fa1
4 changed files with 44 additions and 7 deletions
  1. 5 3
      compiler/rautils.pas
  2. 5 4
      compiler/x86/rax86.pas
  3. 17 0
      tests/webtbf/tw40113b.pp
  4. 17 0
      tests/webtbs/tw40113a.pp

+ 5 - 3
compiler/rautils.pas

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

+ 5 - 4
compiler/x86/rax86.pas

@@ -46,7 +46,7 @@ type
     vbcst   : byte;
     Procedure SetSize(_size:longint;force:boolean);override;
     Procedure SetCorrectSize(opcode:tasmop);override;
-    Function CheckOperand: boolean; override;
+    Function CheckOperand(ins : TInstruction): boolean; override;
     { handles the @Code symbol }
     Procedure SetupCode;
     { handles the @Data symbol }
@@ -258,7 +258,7 @@ begin
     end;
 end;
 
-Function Tx86Operand.CheckOperand: boolean;
+Function Tx86Operand.CheckOperand(ins : TInstruction): boolean;
 var
   ErrorRefStr: string;
 begin
@@ -330,7 +330,8 @@ begin
                 end;
               message1(asmr_w_direct_ebp_neg_offset,ErrorRefStr);
             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
               if current_settings.asmmode in asmmodes_x86_intel then
                 begin
@@ -1837,7 +1838,7 @@ begin
 
   ai:=nil;
   for i:=1 to Ops do
-    if not operands[i].CheckOperand then
+    if not operands[i].CheckOperand(self) then
       exit;
 
 { Get Opsize }

+ 17 - 0
tests/webtbf/tw40113b.pp

@@ -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 - 0
tests/webtbs/tw40113a.pp

@@ -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.