summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-01-22 21:06:07 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2018-01-22 21:06:07 +0000
commitf7dee4cf371b21f37d4f6ec9e8a4c8ce275107d8 (patch)
tree8d3e156dad77fe58a9252f075e772560465dccef
parent588d00693fa3c5d1a3aa6441a55dc99f2040d548 (diff)
downloadfpc-f7dee4cf371b21f37d4f6ec9e8a4c8ce275107d8.tar.gz
* (re)store alignment when doing a $push/$pop
git-svn-id: https://svn.freepascal.org/svn/fpc/trunk@38020 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r--compiler/globals.pas2
-rw-r--r--compiler/scandir.pas8
-rw-r--r--compiler/switches.pas20
-rw-r--r--tests/test/cg/tm128.pp35
4 files changed, 61 insertions, 4 deletions
diff --git a/compiler/globals.pas b/compiler/globals.pas
index e915334dfb..5e2ddf98cc 100644
--- a/compiler/globals.pas
+++ b/compiler/globals.pas
@@ -220,6 +220,8 @@ interface
nextverbosityfullswitch: longint;
nextcallingstr : shortstring;
nextmessagerecord : pmessagestaterecord;
+ nextalignment : talignmentinfo;
+ alignmentchanged,
verbosityfullswitched,
localswitcheschanged : boolean;
end;
diff --git a/compiler/scandir.pas b/compiler/scandir.pas
index e370002462..4b3dca1372 100644
--- a/compiler/scandir.pas
+++ b/compiler/scandir.pas
@@ -26,7 +26,8 @@ unit scandir;
interface
uses
- globtype;
+ globtype,
+ systems;
const
switchesstatestackmax = 20;
@@ -36,6 +37,7 @@ unit scandir;
localsw: tlocalswitches;
verbosity: longint;
pmessage : pmessagestaterecord;
+ alignment : talignmentinfo;
end;
type
@@ -52,7 +54,7 @@ unit scandir;
uses
SysUtils,
cutils,cfileutl,
- globals,systems,widestr,cpuinfo,
+ globals,widestr,cpuinfo,
verbose,comphook,ppu,
scanner,switches,
fmodule,
@@ -1172,6 +1174,7 @@ unit scandir;
Dec(switchesstatestackpos);
recordpendinglocalfullswitch(switchesstatestack[switchesstatestackpos].localsw);
recordpendingverbosityfullswitch(switchesstatestack[switchesstatestackpos].verbosity);
+ recordpendingalignmentfullswitch(switchesstatestack[switchesstatestackpos].alignment);
pendingstate.nextmessagerecord:=switchesstatestack[switchesstatestackpos].pmessage;
{ Reset verbosity and forget previous pmeesage }
RestoreLocalVerbosity(nil);
@@ -1209,6 +1212,7 @@ unit scandir;
switchesstatestack[switchesstatestackpos].localsw:= current_settings.localswitches;
switchesstatestack[switchesstatestackpos].pmessage:= current_settings.pmessage;
switchesstatestack[switchesstatestackpos].verbosity:=status.verbosity;
+ switchesstatestack[switchesstatestackpos].alignment:=current_settings.alignment;
Inc(switchesstatestackpos);
end;
diff --git a/compiler/switches.pas b/compiler/switches.pas
index 62f091efa0..7fdc88d820 100644
--- a/compiler/switches.pas
+++ b/compiler/switches.pas
@@ -26,7 +26,7 @@ unit switches;
interface
uses
- globtype;
+ systems,globtype;
procedure HandleSwitch(switch,state:char);
function CheckSwitch(switch,state:char):boolean;
@@ -37,11 +37,12 @@ procedure recordpendinglocalswitch(sw: tlocalswitch; state: char);
procedure recordpendinglocalfullswitch(const switches: tlocalswitches);
procedure recordpendingverbosityfullswitch(verbosity: longint);
procedure recordpendingcallingswitch(const str: shortstring);
+procedure recordpendingalignmentfullswitch(const alignment : talignmentinfo);
procedure flushpendingswitchesstate;
implementation
uses
- systems,cpuinfo,
+ cpuinfo,
{$ifdef llvm}
{ override optimizer switches }
llvminfo,
@@ -294,6 +295,7 @@ procedure recordpendingverbosityswitch(sw: char; state: char);
pendingstate.nextverbositystr:=pendingstate.nextverbositystr+sw+state;
end;
+
procedure recordpendingmessagestate(msg: longint; state: tmsgstate);
var
pstate : pmessagestaterecord;
@@ -305,6 +307,7 @@ procedure recordpendingmessagestate(msg: longint; state: tmsgstate);
pendingstate.nextmessagerecord:=pstate;
end;
+
procedure recordpendinglocalswitch(sw: tlocalswitch; state: char);
begin
if not pendingstate.localswitcheschanged then
@@ -324,6 +327,13 @@ procedure recordpendinglocalswitch(sw: tlocalswitch; state: char);
end;
+procedure recordpendingalignmentfullswitch(const alignment : talignmentinfo);
+ begin
+ pendingstate.nextalignment:=alignment;
+ pendingstate.alignmentchanged:=true;
+ end;
+
+
procedure recordpendinglocalfullswitch(const switches: tlocalswitches);
begin
pendingstate.nextlocalswitches:=switches;
@@ -361,6 +371,12 @@ procedure flushpendingswitchesstate;
status.verbosity:=pendingstate.nextverbosityfullswitch;
pendingstate.verbosityfullswitched:=false;
end;
+ if pendingstate.alignmentchanged then
+ begin
+ current_settings.alignment:=pendingstate.nextalignment;
+ pendingstate.alignmentchanged:=false;
+ end;
+ { process pending verbosity changes (warnings on, etc) }
if pendingstate.nextverbositystr<>'' then
begin
setverbosity(pendingstate.nextverbositystr);
diff --git a/tests/test/cg/tm128.pp b/tests/test/cg/tm128.pp
new file mode 100644
index 0000000000..b01b87832c
--- /dev/null
+++ b/tests/test/cg/tm128.pp
@@ -0,0 +1,35 @@
+{$ASSERTIONS ON}
+{$packrecords c}
+{$push}
+{$codealign recordmin=16}
+
+type
+ tm128 = record
+ case byte of
+ 1 : (m128_f32 : array[0..3] of single;)
+ end;
+{$pop}
+
+type
+ tm128_unaligned = record
+ case byte of
+ 1 : (m128_f32 : array[0..3] of single;)
+ end;
+
+
+var
+ tr1 : record
+ b : byte;
+ m128 : tm128;
+ end;
+ tr1_unaligned : record
+ b : byte;
+ m128_unaligned : tm128_unaligned;
+ end;
+ d : double;
+
+begin
+ assert((sizeof(tm128))=16);
+ assert((ptruint(@tr1.m128) mod 16)=0);
+ assert((ptruint(@tr1_unaligned.m128_unaligned)-ptruint(@tr1_unaligned.b))=4);
+end.