diff --git a/compiler/rautils.pas b/compiler/rautils.pas index 8d51e3c6ac..57037f5d44 100644 --- a/compiler/rautils.pas +++ b/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; diff --git a/compiler/x86/rax86.pas b/compiler/x86/rax86.pas index 7fbc06704c..11c0214e33 100644 --- a/compiler/x86/rax86.pas +++ b/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 } diff --git a/tests/webtbf/tw40113b.pp b/tests/webtbf/tw40113b.pp new file mode 100644 index 0000000000..e92a7efbc1 --- /dev/null +++ b/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. diff --git a/tests/webtbs/tw40113a.pp b/tests/webtbs/tw40113a.pp new file mode 100644 index 0000000000..4bf2f2e241 --- /dev/null +++ b/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.