+ take care of asmmode in $push/$pop, resolves #41190

This commit is contained in:
florian 2025-03-22 21:15:39 +01:00
parent 1a57a65c5f
commit eb5c61281c
5 changed files with 60 additions and 5 deletions

View File

@ -260,7 +260,8 @@ Const
psf_local_switches_changed,
psf_packenum_changed,
psf_packrecords_changed,
psf_setalloc_changed
psf_setalloc_changed,
psf_asmmode_changed
);
tpendingstateflags = set of tpendingstateflag;
@ -274,6 +275,7 @@ Const
nextpackenum : shortint;
nextpackrecords : shortint;
nextsetalloc : shortint;
nextasmmode : tasmmode;
flags : tpendingstateflags;
end;

View File

@ -57,7 +57,9 @@ implementation
{ codegen }
procinfo,cgbase,
{ assembler reader }
rabase;
rabase,
{ scanner }
switches;
function statement : tnode;forward;
@ -1067,6 +1069,10 @@ implementation
Inside_asm_statement:=true;
asmstat:=nil;
hl:=nil;
{ apply all switch changes as the assembler readers doesn't do so }
flushpendingswitchesstate;
if assigned(asmmodeinfos[current_settings.asmmode]) then
begin
asmreader:=asmmodeinfos[current_settings.asmmode]^.casmreader.create;

View File

@ -41,6 +41,7 @@ unit scandir;
setalloc,
packenum,
packrecords : shortint;
asmmode : tasmmode;
end;
type
@ -312,16 +313,19 @@ unit scandir;
procedure dir_asmmode;
var
s : string;
asmmode: tasmmode;
begin
current_scanner.skipspace;
s:=current_scanner.readid;
If Inside_asm_statement then
Message1(scan_w_no_asm_reader_switch_inside_asm,s);
if s='DEFAULT' then
current_settings.asmmode:=init_settings.asmmode
recordpendingasmmode(init_settings.asmmode)
else
if not SetAsmReadMode(s,current_settings.asmmode) then
Message1(scan_e_illegal_asmmode_specifier,s);
if not SetAsmReadMode(s,asmmode) then
Message1(scan_e_illegal_asmmode_specifier,s)
else
recordpendingasmmode(asmmode);
end;
{$if defined(m68k) or defined(arm)}
@ -1263,6 +1267,7 @@ unit scandir;
recordpendingpackenum(switchesstatestack[switchesstatestackpos].packenum);
recordpendingpackrecords(switchesstatestack[switchesstatestackpos].packrecords);
recordpendingsetalloc(switchesstatestack[switchesstatestackpos].setalloc);
recordpendingasmmode(switchesstatestack[switchesstatestackpos].asmmode);
pendingstate.nextmessagerecord:=switchesstatestack[switchesstatestackpos].pmessage;
{ flushpendingswitchesstate will reset the message state }
current_settings.pmessage:=nil;
@ -1327,6 +1332,11 @@ unit scandir;
else
switchesstatestack[switchesstatestackpos].setalloc:=current_settings.setalloc;
if psf_asmmode_changed in pendingstate.flags then
switchesstatestack[switchesstatestackpos].asmmode:=pendingstate.nextasmmode
else
switchesstatestack[switchesstatestackpos].asmmode:=current_settings.asmmode;
switchesstatestack[switchesstatestackpos].pmessage:=pendingstate.nextmessagerecord;
Inc(switchesstatestackpos);
end;

View File

@ -41,6 +41,7 @@ procedure recordpendingalignmentfullswitch(const alignment : talignmentinfo);
procedure recordpendingsetalloc(alloc:shortint);
procedure recordpendingpackenum(size:shortint);
procedure recordpendingpackrecords(size:shortint);
procedure recordpendingasmmode(asmmode:tasmmode);
procedure flushpendingswitchesstate;
implementation
@ -366,6 +367,13 @@ procedure recordpendingsetalloc(alloc:shortint);
end;
procedure recordpendingasmmode(asmmode:tasmmode);
begin
pendingstate.nextasmmode:=asmmode;
include(pendingstate.flags,psf_asmmode_changed);
end;
procedure recordpendingpackenum(size:shortint);
begin
pendingstate.nextpackenum:=size;
@ -419,6 +427,11 @@ procedure flushpendingswitchesstate;
current_settings.setalloc:=pendingstate.nextsetalloc;
exclude(pendingstate.flags,psf_setalloc_changed);
end;
if psf_asmmode_changed in pendingstate.flags then
begin
current_settings.asmmode:=pendingstate.nextasmmode;
exclude(pendingstate.flags,psf_asmmode_changed);
end;
{ process pending verbosity changes (warnings on, etc) }
if pendingstate.nextverbositystr<>'' then
begin

24
tests/webtbs/tw41190.pp Normal file
View File

@ -0,0 +1,24 @@
{ %cpu=x86_64 }
program test;
{$mode objfpc}
//{$define INTEL}
{$IFDEF INTEL}
{$asmmode intel}
{$push}{$asmmode att}{$pop}
procedure proc2; assembler;
asm
mov rax, 0 // err
end;
{$ELSE}
{$asmmode att}
{$push}{$asmmode intel}{$pop}
procedure proc2; assembler;
asm
movq $0, %rax // err
end;
{$ENDIF}
begin
end.