refactor(codegen-native): extract EmitStaticElemScale for static-array indexing
Phase 1 item 5 of the de-duplication plan. The read-path static-array subscript scaling — `if SAT.LowBound <> 0 then subq $lowbound; imulq $elemsize` applied to an index already in %rax — was spelled out at 7 sites, each casting a different expression to TStaticArrayTypeDesc. Collapse the body into EmitStaticElemScale(ASAT) and pass the resolved type. Only the read sites are touched: the static-array STORE paths compute the element size from a precomputed DAElemType local rather than ASAT.ElementType.RawSize(), so they are deliberately left as-is (the imulq operand differs). Proven byte-identical: native .s for a static-array program (non-zero low bounds, integer + double + record-nested arrays, read and write) is identical to pre-refactor HEAD. All four self-host fixpoints pass; full suite OK (3853 tests) on both QBE-built and native-built test runners.
This commit is contained in:
parent
8a32c3ab57
commit
fdcce09254
|
|
@ -389,6 +389,10 @@ type
|
|||
compound-body inline idiom used for try/finally/except bodies, loop
|
||||
bodies, the program block, and unit init sections. Nil AList is a no-op. }
|
||||
procedure EmitStmtList(AList: TObjectList);
|
||||
{ Given a static-array element index already in %rax, scale it to a byte
|
||||
offset: subtract the (non-zero) low bound, then multiply by the element
|
||||
size. The read-path subscript sites all spell this the same way. }
|
||||
procedure EmitStaticElemScale(ASAT: TStaticArrayTypeDesc);
|
||||
{ Lower a Write/WriteLn call (ANewline = WriteLn). }
|
||||
procedure EmitWrite(ACall: TProcCall; ANewline: Boolean);
|
||||
{ Lower a for loop. }
|
||||
|
|
@ -3551,9 +3555,7 @@ var
|
|||
begin
|
||||
SAT := TStaticArrayTypeDesc(ASub.StrExpr.ResolvedType);
|
||||
Self.EmitExprToEax(ASub.IndexExpr); { index -> %rax }
|
||||
if SAT.LowBound <> 0 then
|
||||
Self.Emit(Format(#9'subq $%d, %%rax', [SAT.LowBound]));
|
||||
Self.Emit(Format(#9'imulq $%d, %%rax', [SAT.ElementType.RawSize()]));
|
||||
Self.EmitStaticElemScale(SAT);
|
||||
{ Base address of the array's inline storage into %rcx. }
|
||||
if (ASub.StrExpr is TIdentExpr) and
|
||||
TIdentExpr(ASub.StrExpr).IsImplicitSelf and
|
||||
|
|
@ -5088,14 +5090,8 @@ begin
|
|||
Self.EmitExprToEax(TStringSubscriptExpr(AExpr).StrExpr);
|
||||
Self.Emit(#9'pushq %rax');
|
||||
Self.EmitExprToEax(TStringSubscriptExpr(AExpr).IndexExpr);
|
||||
if TStaticArrayTypeDesc(
|
||||
TStringSubscriptExpr(AExpr).StrExpr.ResolvedType).LowBound <> 0 then
|
||||
Self.Emit(Format(#9'subq $%d, %%rax',
|
||||
[TStaticArrayTypeDesc(
|
||||
TStringSubscriptExpr(AExpr).StrExpr.ResolvedType).LowBound]));
|
||||
Self.Emit(Format(#9'imulq $%d, %%rax',
|
||||
[TStaticArrayTypeDesc(TStringSubscriptExpr(AExpr).StrExpr.ResolvedType)
|
||||
.ElementType.RawSize()]));
|
||||
Self.EmitStaticElemScale(
|
||||
TStaticArrayTypeDesc(TStringSubscriptExpr(AExpr).StrExpr.ResolvedType));
|
||||
Self.Emit(#9'popq %rcx');
|
||||
Self.Emit(#9'addq %rcx, %rax');
|
||||
Self.EmitLoadFloat('(%rax)',
|
||||
|
|
@ -6957,11 +6953,7 @@ begin
|
|||
Self.EmitExprToEax(SAE.StrExpr);
|
||||
Self.Emit(#9'pushq %rax');
|
||||
Self.EmitExprToEax(SAE.IndexExpr);
|
||||
if TStaticArrayTypeDesc(SAE.StrExpr.ResolvedType).LowBound <> 0 then
|
||||
Self.Emit(Format(#9'subq $%d, %%rax',
|
||||
[TStaticArrayTypeDesc(SAE.StrExpr.ResolvedType).LowBound]));
|
||||
Self.Emit(Format(#9'imulq $%d, %%rax',
|
||||
[TStaticArrayTypeDesc(SAE.StrExpr.ResolvedType).ElementType.RawSize()]));
|
||||
Self.EmitStaticElemScale(TStaticArrayTypeDesc(SAE.StrExpr.ResolvedType));
|
||||
Self.Emit(#9'popq %rcx');
|
||||
Self.Emit(#9'addq %rcx, %rax');
|
||||
{ Record and nested static-array elements evaluate to their address —
|
||||
|
|
@ -7026,9 +7018,7 @@ begin
|
|||
begin
|
||||
SCAT := TStaticArrayTypeDesc(FAE.ConstArrayType);
|
||||
Self.EmitExprToEax(FAE.PropIndexExpr); { index -> %rax }
|
||||
if SCAT.LowBound <> 0 then
|
||||
Self.Emit(Format(#9'subq $%d, %%rax', [SCAT.LowBound]));
|
||||
Self.Emit(Format(#9'imulq $%d, %%rax', [SCAT.ElementType.RawSize()]));
|
||||
Self.EmitStaticElemScale(SCAT);
|
||||
Self.Emit(Format(#9'leaq %s(%%rip), %%rcx',
|
||||
[NativeMangle(FAE.ConstArraySymbol)]));
|
||||
Self.Emit(#9'addq %rcx, %rax');
|
||||
|
|
@ -7292,11 +7282,7 @@ begin
|
|||
begin
|
||||
Self.Emit(#9'pushq %rcx');
|
||||
Self.EmitExprToEax(FAE.PropIndexExpr);
|
||||
if TStaticArrayTypeDesc(FAE.FieldInfo.TypeDesc).LowBound <> 0 then
|
||||
Self.Emit(Format(#9'subq $%d, %%rax',
|
||||
[TStaticArrayTypeDesc(FAE.FieldInfo.TypeDesc).LowBound]));
|
||||
Self.Emit(Format(#9'imulq $%d, %%rax',
|
||||
[TStaticArrayTypeDesc(FAE.FieldInfo.TypeDesc).ElementType.RawSize()]));
|
||||
Self.EmitStaticElemScale(TStaticArrayTypeDesc(FAE.FieldInfo.TypeDesc));
|
||||
Self.Emit(#9'popq %rcx');
|
||||
Self.Emit(#9'addq %rcx, %rax');
|
||||
if TStaticArrayTypeDesc(FAE.FieldInfo.TypeDesc).ElementType.Kind = tyRecord then
|
||||
|
|
@ -7573,11 +7559,7 @@ begin
|
|||
Self.EmitExprToEax(SAE.StrExpr);
|
||||
Self.Emit(#9'pushq %rax');
|
||||
Self.EmitExprToEax(SAE.IndexExpr);
|
||||
if TStaticArrayTypeDesc(SAE.StrExpr.ResolvedType).LowBound <> 0 then
|
||||
Self.Emit(Format(#9'subq $%d, %%rax',
|
||||
[TStaticArrayTypeDesc(SAE.StrExpr.ResolvedType).LowBound]));
|
||||
Self.Emit(Format(#9'imulq $%d, %%rax',
|
||||
[TStaticArrayTypeDesc(SAE.StrExpr.ResolvedType).ElementType.RawSize()]));
|
||||
Self.EmitStaticElemScale(TStaticArrayTypeDesc(SAE.StrExpr.ResolvedType));
|
||||
Self.Emit(#9'popq %rcx');
|
||||
Self.Emit(#9'addq %rcx, %rax');
|
||||
Exit;
|
||||
|
|
@ -7713,11 +7695,7 @@ begin
|
|||
begin
|
||||
Self.Emit(#9'pushq %rcx');
|
||||
Self.EmitExprToEax(FAE.PropIndexExpr);
|
||||
if TStaticArrayTypeDesc(FAE.FieldInfo.TypeDesc).LowBound <> 0 then
|
||||
Self.Emit(Format(#9'subq $%d, %%rax',
|
||||
[TStaticArrayTypeDesc(FAE.FieldInfo.TypeDesc).LowBound]));
|
||||
Self.Emit(Format(#9'imulq $%d, %%rax',
|
||||
[TStaticArrayTypeDesc(FAE.FieldInfo.TypeDesc).ElementType.RawSize()]));
|
||||
Self.EmitStaticElemScale(TStaticArrayTypeDesc(FAE.FieldInfo.TypeDesc));
|
||||
Self.Emit(#9'popq %rcx');
|
||||
Self.Emit(#9'addq %rcx, %rax');
|
||||
end
|
||||
|
|
@ -10811,6 +10789,13 @@ begin
|
|||
Self.EmitStmt(TASTStmt(AList.Items[I]));
|
||||
end;
|
||||
|
||||
procedure TX86_64Backend.EmitStaticElemScale(ASAT: TStaticArrayTypeDesc);
|
||||
begin
|
||||
if ASAT.LowBound <> 0 then
|
||||
Self.Emit(Format(#9'subq $%d, %%rax', [ASAT.LowBound]));
|
||||
Self.Emit(Format(#9'imulq $%d, %%rax', [ASAT.ElementType.RawSize()]));
|
||||
end;
|
||||
|
||||
procedure TX86_64Backend.EmitStmt(AStmt: TASTStmt);
|
||||
var
|
||||
PC: TProcCall;
|
||||
|
|
|
|||
Loading…
Reference in a new issue