* synchronized with trunk

git-svn-id: branches/wasm@46500 -
This commit is contained in:
nickysn 2020-08-19 21:23:36 +00:00
commit 05235a1066
13 changed files with 108 additions and 40 deletions

1
.gitattributes vendored
View File

@ -16594,6 +16594,7 @@ tests/webtbf/tw37272b.pp svneol=native#text/pascal
tests/webtbf/tw37303.pp -text svneol=native#text/pascal tests/webtbf/tw37303.pp -text svneol=native#text/pascal
tests/webtbf/tw3738.pp svneol=native#text/plain tests/webtbf/tw3738.pp svneol=native#text/plain
tests/webtbf/tw3740.pp svneol=native#text/plain tests/webtbf/tw3740.pp svneol=native#text/plain
tests/webtbf/tw37459.pp svneol=native#text/pascal
tests/webtbf/tw37460.pp svneol=native#text/pascal tests/webtbf/tw37460.pp svneol=native#text/pascal
tests/webtbf/tw37462.pp svneol=native#text/pascal tests/webtbf/tw37462.pp svneol=native#text/pascal
tests/webtbf/tw37475.pp svneol=native#text/pascal tests/webtbf/tw37475.pp svneol=native#text/pascal

View File

@ -1745,14 +1745,25 @@ unit cgcpu;
end; end;
OS_32,OS_S32: OS_32,OS_S32:
begin begin
{ Preload the ref base to reduce spilling } { Preload the ref base to a new register to reduce spilling
if (tmpref.base<>NR_NO) and Also preload if the first source reg is used as base or index
to prevent overwriting }
if ((tmpref.base<>NR_NO) and
(tmpref.index<>NR_NO) and (tmpref.index<>NR_NO) and
(getsupreg(tmpref.base)>=first_int_imreg) then (getsupreg(tmpref.base)>=first_int_imreg)) or
(tmpref.base=reg) or
(tmpref.index=reg) then
begin begin
tmpreg:=getaddressregister(list); tmpreg:=getaddressregister(list);
a_load_reg_reg(list,OS_ADDR,OS_ADDR,tmpref.base,tmpreg); a_load_reg_reg(list,OS_ADDR,OS_ADDR,tmpref.base,tmpreg);
tmpref.base:=tmpreg; tmpref.base:=tmpreg;
if tmpref.index=reg then
begin
list.concat(taicpu.op_ref_reg(A_LEA, S_W, tmpref, tmpref.base));
tmpref.index:=NR_NO;
tmpref.offset:=0;
tmpref.scalefactor:=0;
end;
end; end;
list.concat(taicpu.op_reg_ref(A_MOV, S_W, reg, tmpref)); list.concat(taicpu.op_reg_ref(A_MOV, S_W, reg, tmpref));
inc(tmpref.offset, 2); inc(tmpref.offset, 2);
@ -1876,14 +1887,25 @@ unit cgcpu;
end; end;
OS_32,OS_S32: OS_32,OS_S32:
begin begin
{ Preload the ref base to reduce spilling } { Preload the ref base to a new register to reduce spilling
if (tmpref.base<>NR_NO) and Also preload if the first target reg is used as base or index
to prevent overwriting }
if ((tmpref.base<>NR_NO) and
(tmpref.index<>NR_NO) and (tmpref.index<>NR_NO) and
(getsupreg(tmpref.base)>=first_int_imreg) then (getsupreg(tmpref.base)>=first_int_imreg)) or
(tmpref.base=reg) or
(tmpref.index=reg) then
begin begin
tmpreg:=getaddressregister(list); tmpreg:=getaddressregister(list);
a_load_reg_reg(list,OS_ADDR,OS_ADDR,tmpref.base,tmpreg); a_load_reg_reg(list,OS_ADDR,OS_ADDR,tmpref.base,tmpreg);
tmpref.base:=tmpreg; tmpref.base:=tmpreg;
if tmpref.index=reg then
begin
list.concat(taicpu.op_ref_reg(A_LEA, S_W, tmpref, tmpref.base));
tmpref.index:=NR_NO;
tmpref.offset:=0;
tmpref.scalefactor:=0;
end;
end; end;
list.concat(taicpu.op_ref_reg(A_MOV, S_W, tmpref, reg)); list.concat(taicpu.op_ref_reg(A_MOV, S_W, tmpref, reg));
inc(tmpref.offset, 2); inc(tmpref.offset, 2);

View File

@ -149,9 +149,9 @@ implementation
begin begin
if not(tai_symbol(hp).has_value) then if not(tai_symbol(hp).has_value) then
begin begin
if tai_symbol(hp).is_global then //if tai_symbol(hp).is_global then
writer.AsmWriteLn(ApplyAsmSymbolRestrictions(tai_symbol(hp).sym.name) + '::') // writer.AsmWriteLn(ApplyAsmSymbolRestrictions(tai_symbol(hp).sym.name) + '::')
else //else
writer.AsmWriteLn(ApplyAsmSymbolRestrictions(tai_symbol(hp).sym.name) + ':'); writer.AsmWriteLn(ApplyAsmSymbolRestrictions(tai_symbol(hp).sym.name) + ':');
end end
else else

View File

@ -720,6 +720,7 @@ Implementation
if (actasmtoken=AS_PLUS) then if (actasmtoken=AS_PLUS) then
begin begin
l:=BuildConstExpression(true,false); l:=BuildConstExpression(true,false);
if errorcount=0 then
case oper.opr.typ of case oper.opr.typ of
OPR_CONSTANT : OPR_CONSTANT :
inc(oper.opr.val,l); inc(oper.opr.val,l);

View File

@ -1363,6 +1363,8 @@ begin
Consume(tsqlCASE); Consume(tsqlCASE);
Result:=TSQLCaseExpression(CreateElement(TSQLCaseExpression,AParent)); Result:=TSQLCaseExpression(CreateElement(TSQLCaseExpression,AParent));
try try
if CurrentToken<>tsqlWhen then // case A when 1 the 2 when 3 then 4 else 5
Result.Selector:=ParseExprLevel1(AParent,[eoIF]);
while CurrentToken=tsqlWhen do while CurrentToken=tsqlWhen do
begin begin
GetNextToken; GetNextToken;

View File

@ -1469,6 +1469,7 @@ Type
TSQLCaseExpression = Class(TSQLExpression) TSQLCaseExpression = Class(TSQLExpression)
private private
FSelector: TSQLExpression;
FBranches: array of TSQLCaseExpressionBranch; FBranches: array of TSQLCaseExpressionBranch;
FElseBranch: TSQLExpression; FElseBranch: TSQLExpression;
function GetBranch(Index: Integer): TSQLCaseExpressionBranch; function GetBranch(Index: Integer): TSQLCaseExpressionBranch;
@ -1477,6 +1478,7 @@ Type
Destructor Destroy; override; Destructor Destroy; override;
Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override; Function GetAsSQL(Options : TSQLFormatOptions; AIndent : Integer = 0): TSQLStringType; override;
Property Selector: TSQLExpression Read FSelector Write FSelector;
Property BranchCount: Integer Read GetBranchCount; Property BranchCount: Integer Read GetBranchCount;
Procedure AddBranch(ABranch: TSQLCaseExpressionBranch); Procedure AddBranch(ABranch: TSQLCaseExpressionBranch);
Procedure ClearBranches; Procedure ClearBranches;
@ -2137,6 +2139,7 @@ destructor TSQLCaseExpression.Destroy;
begin begin
ClearBranches; ClearBranches;
FreeAndNil(FElseBranch); FreeAndNil(FElseBranch);
FreeAndNil(FSelector);
inherited Destroy; inherited Destroy;
end; end;
@ -2145,6 +2148,8 @@ var
B: TSQLCaseExpressionBranch; B: TSQLCaseExpressionBranch;
begin begin
Result:=SQLKeyWord('CASE',Options)+' '; Result:=SQLKeyWord('CASE',Options)+' ';
if Assigned(Selector) then
Result:=Result+Selector.GetAsSQL(Options,AIndent)+' ';
for B in FBranches do for B in FBranches do
Result:=Result+ Result:=Result+
SQLKeyWord('WHEN ',Options)+B.Condition.GetAsSQL(Options, AIndent)+' '+ SQLKeyWord('WHEN ',Options)+B.Condition.GetAsSQL(Options, AIndent)+' '+

View File

@ -231,6 +231,7 @@ type
procedure TestOr; procedure TestOr;
procedure TestNotOr; procedure TestNotOr;
procedure TestCase; procedure TestCase;
procedure TestCaseWithSelector;
procedure TestAdd; procedure TestAdd;
procedure TestSubtract; procedure TestSubtract;
procedure TestMultiply; procedure TestMultiply;
@ -2268,6 +2269,36 @@ begin
AssertEquals('ELSE result is "c"', 'c', R.Name); AssertEquals('ELSE result is "c"', 'c', R.Name);
end; end;
procedure TTestCheckParser.TestCaseWithSelector;
Var
T : TSQLCaseExpression;
L : TSQLLiteralExpression;
R : TSQLIdentifierName;
begin
T:=TSQLCaseExpression(TestCheck('CASE A WHEN 1 THEN "a" WHEN 2 THEN "b" ELSE "c" END',TSQLCaseExpression));
AssertNotNull('Selector exists',T.Selector);
AssertEquals('Branch count = 2',2,T.BranchCount);
AssertNotNull('Else branch exists',T.ElseBranch);
R:=(T.Selector as TSQLIdentifierExpression).Identifier;
AssertEquals('Selector identifier is "A"', 'A', R.Name);
L:=(T.Branches[0].Condition as TSQLLiteralExpression);
R:=(T.Branches[0].Expression as TSQLIdentifierExpression).Identifier;
AssertEquals('First WHEN Number is 1', 1, (L.Literal as TSQLIntegerLiteral).Value);
AssertEquals('First THEN result is "a"', 'a', R.Name);
L:=(T.Branches[1].Condition as TSQLLiteralExpression);
R:=(T.Branches[1].Expression as TSQLIdentifierExpression).Identifier;
AssertEquals('Second WHEN Number is 2', 2, (L.Literal as TSQLIntegerLiteral).Value);
AssertEquals('Second THEN result is "b"', 'b', R.Name);
R:=(T.ElseBranch as TSQLIdentifierExpression).Identifier;
AssertEquals('ELSE result is "c"', 'c', R.Name);
end;
procedure TTestCheckParser.TestNotBetween; procedure TTestCheckParser.TestNotBetween;
Var Var

View File

@ -63,7 +63,7 @@
procedure RegisterTinyHeapBlock(AAddress: Pointer; ASize:{$ifdef FPC_TINYHEAP_HUGE}LongInt{$else}PtrUInt{$endif}); forward; procedure RegisterTinyHeapBlock(AAddress: Pointer; ASize:{$ifdef FPC_TINYHEAP_HUGE}LongInt{$else}PtrUInt{$endif}); forward;
function EncodeTinyHeapFreeBlockSize(Size: PtrUInt): TTinyHeapFreeBlockSize; inline; function EncodeTinyHeapFreeBlockSize(Size: PtrUInt): TTinyHeapFreeBlockSize; {$ifndef FPC_TINYHEAP_HUGE} inline; {$endif}
begin begin
{$ifdef FPC_TINYHEAP_HUGE} {$ifdef FPC_TINYHEAP_HUGE}
EncodeTinyHeapFreeBlockSize.OfsSize := Size and 15; EncodeTinyHeapFreeBlockSize.OfsSize := Size and 15;
@ -73,7 +73,7 @@
{$endif FPC_TINYHEAP_HUGE} {$endif FPC_TINYHEAP_HUGE}
end; end;
function DecodeTinyHeapFreeBlockSize(Size: TTinyHeapFreeBlockSize): PtrUInt; inline; function DecodeTinyHeapFreeBlockSize(Size: TTinyHeapFreeBlockSize): PtrUInt; {$ifndef FPC_TINYHEAP_HUGE} inline; {$endif}
begin begin
{$ifdef FPC_TINYHEAP_HUGE} {$ifdef FPC_TINYHEAP_HUGE}
DecodeTinyHeapFreeBlockSize := (PtrUInt(Size.SegSize) shl 4) + Size.OfsSize; DecodeTinyHeapFreeBlockSize := (PtrUInt(Size.SegSize) shl 4) + Size.OfsSize;

View File

@ -25,6 +25,7 @@
{$else} {$else}
{$fatal Unknown i8086 memory model.} {$fatal Unknown i8086 memory model.}
{$endif} {$endif}
{$hugecode on}
unit Classes; unit Classes;

View File

@ -25,6 +25,7 @@ interface
{$H+} {$H+}
{$modeswitch typehelpers} {$modeswitch typehelpers}
{$modeswitch advancedrecords} {$modeswitch advancedrecords}
{$hugecode on}
uses uses
{go32,}dos; {go32,}dos;

View File

@ -7,26 +7,26 @@ uses
const const
VMT_COUNT = 100; VMT_COUNT = 100;
ITEM_COUNT = 1000;
type type
TMethodNameTableEntry = packed record TMethodNameTableEntry = packed record
Name: PShortstring; Name: PShortstring;
Addr: Pointer; Addr: CodePointer;
end; end;
TMethodNameTable = packed record TMethodNameTable = packed record
Count: DWord; Count: DWord;
Entries: packed array[0..9999999] of TMethodNameTableEntry; Entries: packed array[0..ITEM_COUNT-1] of TMethodNameTableEntry;
end; end;
PMethodNameTable = ^TMethodNameTable; PMethodNameTable = ^TMethodNameTable;
TPointerArray = packed array[0..9999999] of Pointer; TPointerArray = packed array[0..ITEM_COUNT-1] of Pointer;
PPointerArray = ^TPointerArray; PPointerArray = ^TPointerArray;
PFieldInfo = ^TFieldInfo; PFieldInfo = ^TFieldInfo;
TFieldInfo = packed record TFieldInfo = packed record
FieldOffset: LongWord; FieldOffset: sizeuint;
ClassTypeIndex: Word; ClassTypeIndex: Word;
Name: ShortString; Name: ShortString;
end; end;
@ -38,7 +38,7 @@ type
{$endif FPC_REQUIRES_PROPER_ALIGNMENT} {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
record record
Count: Word; Count: Word;
Entries: array[Word] of TPersistentClass; Entries: array[0..ITEM_COUNT-1] of ^TPersistentClass;
end; end;
PFieldTable = ^TFieldTable; PFieldTable = ^TFieldTable;
@ -103,7 +103,7 @@ var
Cvmt: PPointerArray; Cvmt: PPointerArray;
Cmnt: PMethodNameTable; Cmnt: PMethodNameTable;
Cft: PFieldTable; Cft: PFieldTable;
FieldOffset: LongWord; FieldOffset: sizeuint;
fi: PFieldInfo; fi: PFieldInfo;
Indent: String; Indent: String;
n, idx: Integer; n, idx: Integer;
@ -167,7 +167,7 @@ begin
WriteLn(Indent, 'Field class count: ', Cft^.ClassTable^.Count); WriteLn(Indent, 'Field class count: ', Cft^.ClassTable^.Count);
for n := 0 to Cft^.ClassTable^.Count - 1 do for n := 0 to Cft^.ClassTable^.Count - 1 do
begin begin
WriteLn(Indent, ' ', n, ': ', Cft^.ClassTable^.Entries[n].ClassName); WriteLn(Indent, ' ', n, ': ', Cft^.ClassTable^.Entries[n]^.ClassName);
end; end;
end; end;

View File

@ -7,7 +7,7 @@ uses
const const
VMT_COUNT = 100; VMT_COUNT = 100;
ITEM_COUNT = 1000;
type type
TMethodNameTableEntry = packed record TMethodNameTableEntry = packed record
@ -17,11 +17,11 @@ type
TMethodNameTable = packed record TMethodNameTable = packed record
Count: DWord; Count: DWord;
Entries: packed array[0..9999999] of TMethodNameTableEntry; Entries: packed array[0..ITEM_COUNT-1] of TMethodNameTableEntry;
end; end;
PMethodNameTable = ^TMethodNameTable; PMethodNameTable = ^TMethodNameTable;
TPointerArray = packed array[0..9999999] of Pointer; TPointerArray = packed array[0..ITEM_COUNT-1] of Pointer;
PPointerArray = ^TPointerArray; PPointerArray = ^TPointerArray;
{$M+} {$M+}

4
tests/webtbf/tw37459.pp Normal file
View File

@ -0,0 +1,4 @@
{ %fail }
begin
asm test ptr + ,
// end.