@jhlagado/azm 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -78
- package/dist/src/api-compile.d.ts +0 -2
- package/dist/src/api-compile.js +2 -9
- package/dist/src/assembly/address-planning.js +21 -1
- package/dist/src/assembly/program-emission.js +1 -0
- package/dist/src/cli/parse-args.d.ts +0 -1
- package/dist/src/cli/parse-args.js +0 -7
- package/dist/src/cli/write-artifacts.js +0 -11
- package/dist/src/core/compile.js +192 -9
- package/dist/src/expansion/op-expansion.js +2 -0
- package/dist/src/model/expression.d.ts +4 -0
- package/dist/src/model/source-item.d.ts +11 -0
- package/dist/src/outputs/index.js +0 -2
- package/dist/src/outputs/types.d.ts +3 -16
- package/dist/src/outputs/write-asm80.js +206 -5
- package/dist/src/register-care/analyze.js +36 -8
- package/dist/src/register-care/annotations.js +33 -146
- package/dist/src/register-care/fix.d.ts +2 -0
- package/dist/src/register-care/fix.js +52 -0
- package/dist/src/register-care/instruction-shape.d.ts +11 -0
- package/dist/src/register-care/instruction-shape.js +129 -0
- package/dist/src/register-care/liveness.js +15 -7
- package/dist/src/register-care/profiles.js +4 -0
- package/dist/src/register-care/programModel.js +79 -13
- package/dist/src/register-care/report.d.ts +2 -1
- package/dist/src/register-care/report.js +91 -34
- package/dist/src/register-care/routine-summaries.d.ts +6 -0
- package/dist/src/register-care/routine-summaries.js +89 -0
- package/dist/src/register-care/summaries.d.ts +3 -3
- package/dist/src/register-care/summaries.js +42 -75
- package/dist/{legacy-root-azm/src/registerCare → src/register-care}/summary.js +33 -51
- package/dist/src/register-care/types.d.ts +6 -1
- package/dist/src/semantics/expression-evaluation.d.ts +7 -3
- package/dist/src/semantics/expression-evaluation.js +57 -0
- package/dist/src/source/strip-line-comment.d.ts +2 -0
- package/dist/src/source/strip-line-comment.js +26 -0
- package/dist/src/syntax/directive-aliases.js +9 -10
- package/dist/src/syntax/parse-diagnostics.d.ts +12 -0
- package/dist/src/syntax/parse-diagnostics.js +18 -0
- package/dist/src/syntax/parse-expression.js +34 -9
- package/dist/src/syntax/parse-line.js +150 -54
- package/dist/src/tooling/case-style.js +3 -0
- package/docs/reference/cli.md +6 -4
- package/docs/reference/tooling-api.md +13 -9
- package/package.json +4 -6
- package/dist/legacy-root-azm/src/analysis.d.ts +0 -11
- package/dist/legacy-root-azm/src/analysis.js +0 -41
- package/dist/legacy-root-azm/src/compile.d.ts +0 -10
- package/dist/legacy-root-azm/src/compile.js +0 -186
- package/dist/legacy-root-azm/src/compileShared.d.ts +0 -3
- package/dist/legacy-root-azm/src/compileShared.js +0 -7
- package/dist/legacy-root-azm/src/diagnosticTypes.d.ts +0 -77
- package/dist/legacy-root-azm/src/diagnosticTypes.js +0 -53
- package/dist/legacy-root-azm/src/formats/index.d.ts +0 -7
- package/dist/legacy-root-azm/src/formats/index.js +0 -17
- package/dist/legacy-root-azm/src/formats/range.d.ts +0 -17
- package/dist/legacy-root-azm/src/formats/range.js +0 -45
- package/dist/legacy-root-azm/src/formats/types.d.ts +0 -283
- package/dist/legacy-root-azm/src/formats/types.js +0 -1
- package/dist/legacy-root-azm/src/formats/writeAsm80.d.ts +0 -6
- package/dist/legacy-root-azm/src/formats/writeAsm80.js +0 -86
- package/dist/legacy-root-azm/src/formats/writeBin.d.ts +0 -7
- package/dist/legacy-root-azm/src/formats/writeBin.js +0 -23
- package/dist/legacy-root-azm/src/formats/writeD8m.d.ts +0 -9
- package/dist/legacy-root-azm/src/formats/writeD8m.js +0 -245
- package/dist/legacy-root-azm/src/formats/writeHex.d.ts +0 -8
- package/dist/legacy-root-azm/src/formats/writeHex.js +0 -38
- package/dist/legacy-root-azm/src/formats/writeListing.d.ts +0 -8
- package/dist/legacy-root-azm/src/formats/writeListing.js +0 -83
- package/dist/legacy-root-azm/src/frontend/asm80/asmLine.d.ts +0 -39
- package/dist/legacy-root-azm/src/frontend/asm80/asmLine.js +0 -89
- package/dist/legacy-root-azm/src/frontend/asm80/parseAsmRawValues.d.ts +0 -4
- package/dist/legacy-root-azm/src/frontend/asm80/parseAsmRawValues.js +0 -94
- package/dist/legacy-root-azm/src/frontend/asm80/quoteScan.d.ts +0 -10
- package/dist/legacy-root-azm/src/frontend/asm80/quoteScan.js +0 -25
- package/dist/legacy-root-azm/src/frontend/ast.d.ts +0 -376
- package/dist/legacy-root-azm/src/frontend/ast.js +0 -1
- package/dist/legacy-root-azm/src/frontend/directiveAliases.d.ts +0 -14
- package/dist/legacy-root-azm/src/frontend/directiveAliases.js +0 -189
- package/dist/legacy-root-azm/src/frontend/grammarData.d.ts +0 -14
- package/dist/legacy-root-azm/src/frontend/grammarData.js +0 -65
- package/dist/legacy-root-azm/src/frontend/immExprUtils.d.ts +0 -2
- package/dist/legacy-root-azm/src/frontend/immExprUtils.js +0 -12
- package/dist/legacy-root-azm/src/frontend/parseAsmFlatDirectiveLine.d.ts +0 -17
- package/dist/legacy-root-azm/src/frontend/parseAsmFlatDirectiveLine.js +0 -187
- package/dist/legacy-root-azm/src/frontend/parseAsmInstruction.d.ts +0 -3
- package/dist/legacy-root-azm/src/frontend/parseAsmInstruction.js +0 -73
- package/dist/legacy-root-azm/src/frontend/parseAsmStatements.d.ts +0 -6
- package/dist/legacy-root-azm/src/frontend/parseAsmStatements.js +0 -16
- package/dist/legacy-root-azm/src/frontend/parseAsmStream.d.ts +0 -10
- package/dist/legacy-root-azm/src/frontend/parseAsmStream.js +0 -33
- package/dist/legacy-root-azm/src/frontend/parseAsmTopLevel.d.ts +0 -18
- package/dist/legacy-root-azm/src/frontend/parseAsmTopLevel.js +0 -34
- package/dist/legacy-root-azm/src/frontend/parseDiagnostics.d.ts +0 -9
- package/dist/legacy-root-azm/src/frontend/parseDiagnostics.js +0 -16
- package/dist/legacy-root-azm/src/frontend/parseEnum.d.ts +0 -12
- package/dist/legacy-root-azm/src/frontend/parseEnum.js +0 -70
- package/dist/legacy-root-azm/src/frontend/parseImm.d.ts +0 -10
- package/dist/legacy-root-azm/src/frontend/parseImm.js +0 -397
- package/dist/legacy-root-azm/src/frontend/parseLogicalLines.d.ts +0 -11
- package/dist/legacy-root-azm/src/frontend/parseLogicalLines.js +0 -94
- package/dist/legacy-root-azm/src/frontend/parseOp.d.ts +0 -25
- package/dist/legacy-root-azm/src/frontend/parseOp.js +0 -120
- package/dist/legacy-root-azm/src/frontend/parseOpHeader.d.ts +0 -20
- package/dist/legacy-root-azm/src/frontend/parseOpHeader.js +0 -32
- package/dist/legacy-root-azm/src/frontend/parseOperands.d.ts +0 -4
- package/dist/legacy-root-azm/src/frontend/parseOperands.js +0 -290
- package/dist/legacy-root-azm/src/frontend/parseParams.d.ts +0 -6
- package/dist/legacy-root-azm/src/frontend/parseParams.js +0 -62
- package/dist/legacy-root-azm/src/frontend/parseParserRecovery.d.ts +0 -12
- package/dist/legacy-root-azm/src/frontend/parseParserRecovery.js +0 -17
- package/dist/legacy-root-azm/src/frontend/parseParserShared.d.ts +0 -2
- package/dist/legacy-root-azm/src/frontend/parseParserShared.js +0 -8
- package/dist/legacy-root-azm/src/frontend/parseRawDataDirectiveStart.d.ts +0 -1
- package/dist/legacy-root-azm/src/frontend/parseRawDataDirectiveStart.js +0 -3
- package/dist/legacy-root-azm/src/frontend/parseRawDataDirectives.d.ts +0 -7
- package/dist/legacy-root-azm/src/frontend/parseRawDataDirectives.js +0 -142
- package/dist/legacy-root-azm/src/frontend/parseRecordFieldDecl.d.ts +0 -34
- package/dist/legacy-root-azm/src/frontend/parseRecordFieldDecl.js +0 -177
- package/dist/legacy-root-azm/src/frontend/parseSourceItemDispatch.d.ts +0 -46
- package/dist/legacy-root-azm/src/frontend/parseSourceItemDispatch.js +0 -53
- package/dist/legacy-root-azm/src/frontend/parseSourceItemTable.d.ts +0 -16
- package/dist/legacy-root-azm/src/frontend/parseSourceItemTable.js +0 -68
- package/dist/legacy-root-azm/src/frontend/parseTopLevelCommon.d.ts +0 -11
- package/dist/legacy-root-azm/src/frontend/parseTopLevelCommon.js +0 -50
- package/dist/legacy-root-azm/src/frontend/parseTypes.d.ts +0 -24
- package/dist/legacy-root-azm/src/frontend/parseTypes.js +0 -77
- package/dist/legacy-root-azm/src/frontend/parser.d.ts +0 -11
- package/dist/legacy-root-azm/src/frontend/parser.js +0 -88
- package/dist/legacy-root-azm/src/frontend/source.d.ts +0 -28
- package/dist/legacy-root-azm/src/frontend/source.js +0 -58
- package/dist/legacy-root-azm/src/frontend/sourceExtensions.d.ts +0 -2
- package/dist/legacy-root-azm/src/frontend/sourceExtensions.js +0 -6
- package/dist/legacy-root-azm/src/lintCaseStyle.d.ts +0 -4
- package/dist/legacy-root-azm/src/lintCaseStyle.js +0 -129
- package/dist/legacy-root-azm/src/lowering/asmDirectiveLowering.d.ts +0 -4
- package/dist/legacy-root-azm/src/lowering/asmDirectiveLowering.js +0 -229
- package/dist/legacy-root-azm/src/lowering/asmDirectiveTraversal.d.ts +0 -47
- package/dist/legacy-root-azm/src/lowering/asmDirectiveTraversal.js +0 -52
- package/dist/legacy-root-azm/src/lowering/asmEquResolution.d.ts +0 -8
- package/dist/legacy-root-azm/src/lowering/asmEquResolution.js +0 -69
- package/dist/legacy-root-azm/src/lowering/asmInstructionLdHelpers.d.ts +0 -15
- package/dist/legacy-root-azm/src/lowering/asmInstructionLdHelpers.js +0 -102
- package/dist/legacy-root-azm/src/lowering/asmInstructionLowering.d.ts +0 -5
- package/dist/legacy-root-azm/src/lowering/asmInstructionLowering.js +0 -54
- package/dist/legacy-root-azm/src/lowering/asmInstructionStream.d.ts +0 -46
- package/dist/legacy-root-azm/src/lowering/asmInstructionStream.js +0 -51
- package/dist/legacy-root-azm/src/lowering/asmLoweringBranchCall.d.ts +0 -43
- package/dist/legacy-root-azm/src/lowering/asmLoweringBranchCall.js +0 -254
- package/dist/legacy-root-azm/src/lowering/asmLoweringHost.d.ts +0 -23
- package/dist/legacy-root-azm/src/lowering/asmLoweringHost.js +0 -1
- package/dist/legacy-root-azm/src/lowering/asmLoweringLd.d.ts +0 -28
- package/dist/legacy-root-azm/src/lowering/asmLoweringLd.js +0 -144
- package/dist/legacy-root-azm/src/lowering/asmRangeLowering.d.ts +0 -17
- package/dist/legacy-root-azm/src/lowering/asmRangeLowering.js +0 -39
- package/dist/legacy-root-azm/src/lowering/asmRawDataLowering.d.ts +0 -16
- package/dist/legacy-root-azm/src/lowering/asmRawDataLowering.js +0 -209
- package/dist/legacy-root-azm/src/lowering/asmSourceEmitter.d.ts +0 -4
- package/dist/legacy-root-azm/src/lowering/asmSourceEmitter.js +0 -9
- package/dist/legacy-root-azm/src/lowering/asmSourceInstructionLowering.d.ts +0 -4
- package/dist/legacy-root-azm/src/lowering/asmSourceInstructionLowering.js +0 -14
- package/dist/legacy-root-azm/src/lowering/asmUtils.d.ts +0 -13
- package/dist/legacy-root-azm/src/lowering/asmUtils.js +0 -105
- package/dist/legacy-root-azm/src/lowering/assemblerFlowSetup.d.ts +0 -54
- package/dist/legacy-root-azm/src/lowering/assemblerFlowSetup.js +0 -128
- package/dist/legacy-root-azm/src/lowering/assemblerLoweringContext.d.ts +0 -151
- package/dist/legacy-root-azm/src/lowering/assemblerLoweringContext.js +0 -16
- package/dist/legacy-root-azm/src/lowering/assemblerLoweringContextSplit.d.ts +0 -7
- package/dist/legacy-root-azm/src/lowering/assemblerLoweringContextSplit.js +0 -75
- package/dist/legacy-root-azm/src/lowering/assemblerLoweringPhases.d.ts +0 -66
- package/dist/legacy-root-azm/src/lowering/assemblerLoweringPhases.js +0 -166
- package/dist/legacy-root-azm/src/lowering/bytePlacement.d.ts +0 -7
- package/dist/legacy-root-azm/src/lowering/bytePlacement.js +0 -37
- package/dist/legacy-root-azm/src/lowering/capabilities.d.ts +0 -67
- package/dist/legacy-root-azm/src/lowering/capabilities.js +0 -1
- package/dist/legacy-root-azm/src/lowering/eaResolution.d.ts +0 -58
- package/dist/legacy-root-azm/src/lowering/eaResolution.js +0 -159
- package/dist/legacy-root-azm/src/lowering/emissionCore.d.ts +0 -17
- package/dist/legacy-root-azm/src/lowering/emissionCore.js +0 -21
- package/dist/legacy-root-azm/src/lowering/emit.d.ts +0 -17
- package/dist/legacy-root-azm/src/lowering/emit.js +0 -46
- package/dist/legacy-root-azm/src/lowering/emitContextBuilder.d.ts +0 -63
- package/dist/legacy-root-azm/src/lowering/emitContextBuilder.js +0 -41
- package/dist/legacy-root-azm/src/lowering/emitFinalization.d.ts +0 -61
- package/dist/legacy-root-azm/src/lowering/emitFinalization.js +0 -66
- package/dist/legacy-root-azm/src/lowering/emitFinalizationSetup.d.ts +0 -19
- package/dist/legacy-root-azm/src/lowering/emitFinalizationSetup.js +0 -26
- package/dist/legacy-root-azm/src/lowering/emitPhase1BuildProgramLoweringContext.d.ts +0 -7
- package/dist/legacy-root-azm/src/lowering/emitPhase1BuildProgramLoweringContext.js +0 -119
- package/dist/legacy-root-azm/src/lowering/emitPhase1Helpers.d.ts +0 -4
- package/dist/legacy-root-azm/src/lowering/emitPhase1Helpers.js +0 -12
- package/dist/legacy-root-azm/src/lowering/emitPhase1Types.d.ts +0 -21
- package/dist/legacy-root-azm/src/lowering/emitPhase1Types.js +0 -1
- package/dist/legacy-root-azm/src/lowering/emitPhase1WirePipeline.d.ts +0 -70
- package/dist/legacy-root-azm/src/lowering/emitPhase1WirePipeline.js +0 -203
- package/dist/legacy-root-azm/src/lowering/emitPhase1Workspace.d.ts +0 -82
- package/dist/legacy-root-azm/src/lowering/emitPhase1Workspace.js +0 -55
- package/dist/legacy-root-azm/src/lowering/emitPipeline.d.ts +0 -121
- package/dist/legacy-root-azm/src/lowering/emitPipeline.js +0 -57
- package/dist/legacy-root-azm/src/lowering/emitProgramContext.d.ts +0 -39
- package/dist/legacy-root-azm/src/lowering/emitProgramContext.js +0 -29
- package/dist/legacy-root-azm/src/lowering/emitState.d.ts +0 -90
- package/dist/legacy-root-azm/src/lowering/emitState.js +0 -124
- package/dist/legacy-root-azm/src/lowering/fixupBaseResolution.d.ts +0 -7
- package/dist/legacy-root-azm/src/lowering/fixupBaseResolution.js +0 -23
- package/dist/legacy-root-azm/src/lowering/fixupEmission.d.ts +0 -64
- package/dist/legacy-root-azm/src/lowering/fixupEmission.js +0 -199
- package/dist/legacy-root-azm/src/lowering/immMath.d.ts +0 -2
- package/dist/legacy-root-azm/src/lowering/immMath.js +0 -34
- package/dist/legacy-root-azm/src/lowering/inputAssets.d.ts +0 -7
- package/dist/legacy-root-azm/src/lowering/inputAssets.js +0 -106
- package/dist/legacy-root-azm/src/lowering/ldEncoding.d.ts +0 -15
- package/dist/legacy-root-azm/src/lowering/ldEncoding.js +0 -12
- package/dist/legacy-root-azm/src/lowering/ldEncodingRegMemHelpers.d.ts +0 -5
- package/dist/legacy-root-azm/src/lowering/ldEncodingRegMemHelpers.js +0 -124
- package/dist/legacy-root-azm/src/lowering/ldFormSelection.d.ts +0 -26
- package/dist/legacy-root-azm/src/lowering/ldFormSelection.js +0 -92
- package/dist/legacy-root-azm/src/lowering/ldLowering.d.ts +0 -7
- package/dist/legacy-root-azm/src/lowering/ldLowering.js +0 -13
- package/dist/legacy-root-azm/src/lowering/loweredAsmByteEmission.d.ts +0 -23
- package/dist/legacy-root-azm/src/lowering/loweredAsmByteEmission.js +0 -185
- package/dist/legacy-root-azm/src/lowering/loweredAsmPlacement.d.ts +0 -13
- package/dist/legacy-root-azm/src/lowering/loweredAsmPlacement.js +0 -86
- package/dist/legacy-root-azm/src/lowering/loweredAsmStreamRecording.d.ts +0 -27
- package/dist/legacy-root-azm/src/lowering/loweredAsmStreamRecording.js +0 -215
- package/dist/legacy-root-azm/src/lowering/loweredAsmTypes.d.ts +0 -202
- package/dist/legacy-root-azm/src/lowering/loweredAsmTypes.js +0 -1
- package/dist/legacy-root-azm/src/lowering/loweredFormat.d.ts +0 -3
- package/dist/legacy-root-azm/src/lowering/loweredFormat.js +0 -26
- package/dist/legacy-root-azm/src/lowering/loweredItemSize.d.ts +0 -4
- package/dist/legacy-root-azm/src/lowering/loweredItemSize.js +0 -17
- package/dist/legacy-root-azm/src/lowering/loweringDiagnostics.d.ts +0 -9
- package/dist/legacy-root-azm/src/lowering/loweringDiagnostics.js +0 -55
- package/dist/legacy-root-azm/src/lowering/loweringTypes.d.ts +0 -27
- package/dist/legacy-root-azm/src/lowering/loweringTypes.js +0 -1
- package/dist/legacy-root-azm/src/lowering/opCandidateRegistry.d.ts +0 -9
- package/dist/legacy-root-azm/src/lowering/opCandidateRegistry.js +0 -9
- package/dist/legacy-root-azm/src/lowering/opExpansionExecution.d.ts +0 -15
- package/dist/legacy-root-azm/src/lowering/opExpansionExecution.js +0 -45
- package/dist/legacy-root-azm/src/lowering/opExpansionOrchestration.d.ts +0 -15
- package/dist/legacy-root-azm/src/lowering/opExpansionOrchestration.js +0 -88
- package/dist/legacy-root-azm/src/lowering/opExpansionStream.d.ts +0 -12
- package/dist/legacy-root-azm/src/lowering/opExpansionStream.js +0 -176
- package/dist/legacy-root-azm/src/lowering/opMatching.d.ts +0 -52
- package/dist/legacy-root-azm/src/lowering/opMatching.js +0 -355
- package/dist/legacy-root-azm/src/lowering/opSubstitution.d.ts +0 -13
- package/dist/legacy-root-azm/src/lowering/opSubstitution.js +0 -175
- package/dist/legacy-root-azm/src/lowering/prescanTypes.d.ts +0 -7
- package/dist/legacy-root-azm/src/lowering/prescanTypes.js +0 -1
- package/dist/legacy-root-azm/src/lowering/programLowering.d.ts +0 -144
- package/dist/legacy-root-azm/src/lowering/programLowering.js +0 -2
- package/dist/legacy-root-azm/src/lowering/programLoweringDeclarations.d.ts +0 -5
- package/dist/legacy-root-azm/src/lowering/programLoweringDeclarations.js +0 -5
- package/dist/legacy-root-azm/src/lowering/programLoweringFinalize.d.ts +0 -18
- package/dist/legacy-root-azm/src/lowering/programLoweringFinalize.js +0 -115
- package/dist/legacy-root-azm/src/lowering/programLoweringTraversal.d.ts +0 -2
- package/dist/legacy-root-azm/src/lowering/programLoweringTraversal.js +0 -93
- package/dist/legacy-root-azm/src/lowering/programPrescan.d.ts +0 -3
- package/dist/legacy-root-azm/src/lowering/programPrescan.js +0 -37
- package/dist/legacy-root-azm/src/lowering/traceFormat.d.ts +0 -13
- package/dist/legacy-root-azm/src/lowering/traceFormat.js +0 -211
- package/dist/legacy-root-azm/src/packageInfo.d.ts +0 -1
- package/dist/legacy-root-azm/src/packageInfo.js +0 -15
- package/dist/legacy-root-azm/src/pathCompare.d.ts +0 -3
- package/dist/legacy-root-azm/src/pathCompare.js +0 -26
- package/dist/legacy-root-azm/src/pipeline.d.ts +0 -91
- package/dist/legacy-root-azm/src/pipeline.js +0 -1
- package/dist/legacy-root-azm/src/registerCare/analyze.d.ts +0 -24
- package/dist/legacy-root-azm/src/registerCare/analyze.js +0 -327
- package/dist/legacy-root-azm/src/registerCare/boundaryHints.d.ts +0 -2
- package/dist/legacy-root-azm/src/registerCare/boundaryHints.js +0 -10
- package/dist/legacy-root-azm/src/registerCare/carriers.d.ts +0 -4
- package/dist/legacy-root-azm/src/registerCare/carriers.js +0 -78
- package/dist/legacy-root-azm/src/registerCare/controlFlow.d.ts +0 -5
- package/dist/legacy-root-azm/src/registerCare/controlFlow.js +0 -35
- package/dist/legacy-root-azm/src/registerCare/fix.d.ts +0 -11
- package/dist/legacy-root-azm/src/registerCare/fix.js +0 -119
- package/dist/legacy-root-azm/src/registerCare/liveness.d.ts +0 -7
- package/dist/legacy-root-azm/src/registerCare/liveness.js +0 -227
- package/dist/legacy-root-azm/src/registerCare/profiles.d.ts +0 -11
- package/dist/legacy-root-azm/src/registerCare/profiles.js +0 -45
- package/dist/legacy-root-azm/src/registerCare/programModel.d.ts +0 -3
- package/dist/legacy-root-azm/src/registerCare/programModel.js +0 -181
- package/dist/legacy-root-azm/src/registerCare/report.d.ts +0 -5
- package/dist/legacy-root-azm/src/registerCare/report.js +0 -139
- package/dist/legacy-root-azm/src/registerCare/smartComments.d.ts +0 -5
- package/dist/legacy-root-azm/src/registerCare/smartComments.js +0 -247
- package/dist/legacy-root-azm/src/registerCare/types.d.ts +0 -154
- package/dist/legacy-root-azm/src/registerCare/types.js +0 -1
- package/dist/legacy-root-azm/src/semantics/declVisitor.d.ts +0 -5
- package/dist/legacy-root-azm/src/semantics/declVisitor.js +0 -11
- package/dist/legacy-root-azm/src/semantics/env.d.ts +0 -28
- package/dist/legacy-root-azm/src/semantics/env.js +0 -432
- package/dist/legacy-root-azm/src/semantics/layout.d.ts +0 -21
- package/dist/legacy-root-azm/src/semantics/layout.js +0 -226
- package/dist/legacy-root-azm/src/semantics/layoutCastFold.d.ts +0 -22
- package/dist/legacy-root-azm/src/semantics/layoutCastFold.js +0 -118
- package/dist/legacy-root-azm/src/semantics/semanticsDiagnostics.d.ts +0 -2
- package/dist/legacy-root-azm/src/semantics/semanticsDiagnostics.js +0 -4
- package/dist/legacy-root-azm/src/semantics/typeQueries.d.ts +0 -31
- package/dist/legacy-root-azm/src/semantics/typeQueries.js +0 -124
- package/dist/legacy-root-azm/src/sourceIncludeExpansion.d.ts +0 -17
- package/dist/legacy-root-azm/src/sourceIncludeExpansion.js +0 -124
- package/dist/legacy-root-azm/src/sourceIncludePaths.d.ts +0 -1
- package/dist/legacy-root-azm/src/sourceIncludePaths.js +0 -12
- package/dist/legacy-root-azm/src/sourceLoader.d.ts +0 -15
- package/dist/legacy-root-azm/src/sourceLoader.js +0 -118
- package/dist/legacy-root-azm/src/z80/effects.d.ts +0 -3
- package/dist/legacy-root-azm/src/z80/effects.js +0 -516
- package/dist/legacy-root-azm/src/z80/encode.d.ts +0 -10
- package/dist/legacy-root-azm/src/z80/encode.js +0 -412
- package/dist/legacy-root-azm/src/z80/encodeAlu.d.ts +0 -7
- package/dist/legacy-root-azm/src/z80/encodeAlu.js +0 -219
- package/dist/legacy-root-azm/src/z80/encodeBitOps.d.ts +0 -7
- package/dist/legacy-root-azm/src/z80/encodeBitOps.js +0 -123
- package/dist/legacy-root-azm/src/z80/encodeContext.d.ts +0 -29
- package/dist/legacy-root-azm/src/z80/encodeContext.js +0 -1
- package/dist/legacy-root-azm/src/z80/encodeControl.d.ts +0 -26
- package/dist/legacy-root-azm/src/z80/encodeControl.js +0 -180
- package/dist/legacy-root-azm/src/z80/encodeCoreOps.d.ts +0 -7
- package/dist/legacy-root-azm/src/z80/encodeCoreOps.js +0 -131
- package/dist/legacy-root-azm/src/z80/encodeIo.d.ts +0 -9
- package/dist/legacy-root-azm/src/z80/encodeIo.js +0 -128
- package/dist/legacy-root-azm/src/z80/encodeLd.d.ts +0 -13
- package/dist/legacy-root-azm/src/z80/encodeLd.js +0 -273
- package/dist/legacy-root-azm/src/z80/encoderRegistry.d.ts +0 -13
- package/dist/legacy-root-azm/src/z80/encoderRegistry.js +0 -169
- package/dist/src/outputs/write-listing.d.ts +0 -2
- package/dist/src/outputs/write-listing.js +0 -79
- /package/dist/{legacy-root-azm/src/registerCare → src/register-care}/annotate.d.ts +0 -0
- /package/dist/{legacy-root-azm/src/registerCare → src/register-care}/annotate.js +0 -0
- /package/dist/{legacy-root-azm/src/registerCare → src/register-care}/sourceText.d.ts +0 -0
- /package/dist/{legacy-root-azm/src/registerCare → src/register-care}/sourceText.js +0 -0
- /package/dist/{legacy-root-azm/src/registerCare → src/register-care}/summary.d.ts +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
export function instructionHead(item) {
|
|
2
|
+
return item.instruction.mnemonic.toLowerCase();
|
|
3
|
+
}
|
|
4
|
+
export function regName(operand) {
|
|
5
|
+
if (operand === undefined)
|
|
6
|
+
return undefined;
|
|
7
|
+
switch (operand.kind) {
|
|
8
|
+
case 'reg8':
|
|
9
|
+
return operand.register.toUpperCase();
|
|
10
|
+
case 'reg16':
|
|
11
|
+
return operand.register.toUpperCase();
|
|
12
|
+
case 'reg-index16':
|
|
13
|
+
return operand.register.toUpperCase();
|
|
14
|
+
case 'reg-half-index':
|
|
15
|
+
return operand.register.toUpperCase();
|
|
16
|
+
default:
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function immValue(operand) {
|
|
21
|
+
if (operand?.kind !== 'imm')
|
|
22
|
+
return undefined;
|
|
23
|
+
const expression = operand.expression;
|
|
24
|
+
return expression.kind === 'number' ? expression.value : undefined;
|
|
25
|
+
}
|
|
26
|
+
export function instructionOperandCount(instruction) {
|
|
27
|
+
switch (instruction.mnemonic) {
|
|
28
|
+
case 'ret':
|
|
29
|
+
case 'ret-cc':
|
|
30
|
+
return instruction.mnemonic === 'ret' ? 0 : 1;
|
|
31
|
+
case 'ld':
|
|
32
|
+
return 2;
|
|
33
|
+
case 'ex':
|
|
34
|
+
return 2;
|
|
35
|
+
case 'jp':
|
|
36
|
+
case 'jp-cc':
|
|
37
|
+
case 'jr':
|
|
38
|
+
case 'jr-cc':
|
|
39
|
+
case 'djnz':
|
|
40
|
+
case 'call':
|
|
41
|
+
case 'call-cc':
|
|
42
|
+
return 1;
|
|
43
|
+
case 'add':
|
|
44
|
+
case 'adc':
|
|
45
|
+
case 'sbc':
|
|
46
|
+
return 'target' in instruction ? 2 : 1;
|
|
47
|
+
case 'sub':
|
|
48
|
+
case 'and':
|
|
49
|
+
case 'or':
|
|
50
|
+
case 'xor':
|
|
51
|
+
case 'cp':
|
|
52
|
+
return 1;
|
|
53
|
+
default:
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function instructionOperand(instruction, index) {
|
|
58
|
+
switch (instruction.mnemonic) {
|
|
59
|
+
case 'ld':
|
|
60
|
+
return index === 0 ? instruction.target : index === 1 ? instruction.source : undefined;
|
|
61
|
+
case 'ex': {
|
|
62
|
+
if (index === 0) {
|
|
63
|
+
return instruction.form === 'de-hl'
|
|
64
|
+
? { kind: 'reg16', register: 'de' }
|
|
65
|
+
: instruction.form === 'af-af'
|
|
66
|
+
? { kind: 'reg16', register: 'af' }
|
|
67
|
+
: undefined;
|
|
68
|
+
}
|
|
69
|
+
if (index === 1) {
|
|
70
|
+
return instruction.form === 'de-hl'
|
|
71
|
+
? { kind: 'reg16', register: 'hl' }
|
|
72
|
+
: undefined;
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
case 'add':
|
|
77
|
+
case 'adc':
|
|
78
|
+
case 'sbc':
|
|
79
|
+
if ('target' in instruction) {
|
|
80
|
+
return index === 0 ? instruction.target : index === 1 ? instruction.source : undefined;
|
|
81
|
+
}
|
|
82
|
+
return index === 0 ? instruction.source : undefined;
|
|
83
|
+
case 'sub':
|
|
84
|
+
case 'and':
|
|
85
|
+
case 'or':
|
|
86
|
+
case 'xor':
|
|
87
|
+
case 'cp':
|
|
88
|
+
return index === 0 ? instruction.source : undefined;
|
|
89
|
+
default:
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export function isUnconditionalReturnInstruction(item) {
|
|
94
|
+
const head = instructionHead(item);
|
|
95
|
+
if (head === 'ret')
|
|
96
|
+
return item.instruction.mnemonic === 'ret';
|
|
97
|
+
return head === 'retn' || head === 'reti';
|
|
98
|
+
}
|
|
99
|
+
export function isPureTokenTransferInstruction(item) {
|
|
100
|
+
const head = instructionHead(item);
|
|
101
|
+
if (head === 'ex')
|
|
102
|
+
return true;
|
|
103
|
+
if (head !== 'ld' || instructionOperandCount(item.instruction) !== 2)
|
|
104
|
+
return false;
|
|
105
|
+
const dst = instructionOperand(item.instruction, 0);
|
|
106
|
+
const src = instructionOperand(item.instruction, 1);
|
|
107
|
+
if (regName(dst) === undefined)
|
|
108
|
+
return false;
|
|
109
|
+
return regName(src) !== undefined || src?.kind === 'imm';
|
|
110
|
+
}
|
|
111
|
+
export function isAccumulatorSelfOperand(item) {
|
|
112
|
+
const inst = item.instruction;
|
|
113
|
+
if (inst.mnemonic === 'or' || inst.mnemonic === 'and' || inst.mnemonic === 'xor') {
|
|
114
|
+
return inst.source.kind === 'reg8' && inst.source.register === 'a';
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
export function isImmediateZeroOperand(item) {
|
|
119
|
+
const inst = item.instruction;
|
|
120
|
+
if (inst.mnemonic !== 'cp')
|
|
121
|
+
return false;
|
|
122
|
+
return immValue(inst.source) === 0;
|
|
123
|
+
}
|
|
124
|
+
export function isRegisterOperand(item, index, name) {
|
|
125
|
+
if (item === undefined)
|
|
126
|
+
return false;
|
|
127
|
+
const operand = instructionOperand(item.instruction, index);
|
|
128
|
+
return regName(operand) === name.toUpperCase();
|
|
129
|
+
}
|
|
@@ -48,10 +48,7 @@ function hintUnitsForLine(hints, file, callLine) {
|
|
|
48
48
|
return prior?.comment.kind === 'expectOut' ? unique(prior.comment.carriers) : [];
|
|
49
49
|
}
|
|
50
50
|
function outputUnits(summary) {
|
|
51
|
-
return unique(
|
|
52
|
-
...(summary.valueRelations?.flatMap((relation) => relation.out) ?? []),
|
|
53
|
-
...(summary.mayOutput ?? []),
|
|
54
|
-
]);
|
|
51
|
+
return unique(summary.valueRelations.flatMap((relation) => relation.out));
|
|
55
52
|
}
|
|
56
53
|
function setEqual(left, right) {
|
|
57
54
|
if (left.size !== right.size)
|
|
@@ -148,7 +145,7 @@ export function findRegisterCareConflicts(routine, summaries, hints) {
|
|
|
148
145
|
for (const unit of outputUnits(summary))
|
|
149
146
|
accepted.add(unit);
|
|
150
147
|
const carriers = unique(summary.mayWrite.filter((unit) => liveOut[index].has(unit) && !accepted.has(unit)));
|
|
151
|
-
if (carriers.length > 0
|
|
148
|
+
if (carriers.length > 0) {
|
|
152
149
|
conflicts.push({
|
|
153
150
|
file: item.file,
|
|
154
151
|
line: item.line,
|
|
@@ -171,8 +168,19 @@ export function findCallerOutputCandidateObservations(routines, summaries) {
|
|
|
171
168
|
for (const routine of routines) {
|
|
172
169
|
const { liveOut } = liveSetsForRoutine(routine, summaries);
|
|
173
170
|
for (const { item, index, boundary, target, summary } of resolvedBoundariesForRoutine(routine, summaries)) {
|
|
174
|
-
const
|
|
175
|
-
const
|
|
171
|
+
const intentionalOutputs = new Set(outputUnits(summary));
|
|
172
|
+
const carrierSources = [];
|
|
173
|
+
for (const unit of summary.mayWrite) {
|
|
174
|
+
if (liveOut[index].has(unit) && !intentionalOutputs.has(unit)) {
|
|
175
|
+
carrierSources.push(unit);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
for (const unit of intentionalOutputs) {
|
|
179
|
+
if (liveOut[index].has(unit)) {
|
|
180
|
+
carrierSources.push(unit);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const carriers = unique(carrierSources);
|
|
176
184
|
if (carriers.length > 0) {
|
|
177
185
|
out.push({
|
|
178
186
|
file: item.file,
|
|
@@ -23,6 +23,8 @@ export function getRegisterCareProfile(name) {
|
|
|
23
23
|
mayOutput: [],
|
|
24
24
|
preserved: ['B', 'C', 'D', 'E', 'H', 'L'],
|
|
25
25
|
valueRelations: [],
|
|
26
|
+
stackBalanced: true,
|
|
27
|
+
hasUnknownStackEffect: false,
|
|
26
28
|
},
|
|
27
29
|
],
|
|
28
30
|
]),
|
|
@@ -36,6 +38,8 @@ export function getRegisterCareProfile(name) {
|
|
|
36
38
|
mayOutput: ['A', 'carry', 'zero'],
|
|
37
39
|
preserved: ['B', 'C', 'D', 'E', 'H', 'L'],
|
|
38
40
|
valueRelations: [{ out: ['A', 'carry', 'zero'], from: [] }],
|
|
41
|
+
stackBalanced: true,
|
|
42
|
+
hasUnknownStackEffect: false,
|
|
39
43
|
},
|
|
40
44
|
],
|
|
41
45
|
]),
|
|
@@ -13,6 +13,21 @@ function instructionCallTarget(item) {
|
|
|
13
13
|
}
|
|
14
14
|
return undefined;
|
|
15
15
|
}
|
|
16
|
+
function instructionTailJumpTarget(item, entryNames) {
|
|
17
|
+
if (item.kind !== 'instruction')
|
|
18
|
+
return undefined;
|
|
19
|
+
const mnemonic = item.instruction.mnemonic;
|
|
20
|
+
if (mnemonic === 'jp-cc' && entryNames === undefined)
|
|
21
|
+
return undefined;
|
|
22
|
+
if (mnemonic !== 'jp' && mnemonic !== 'jp-cc')
|
|
23
|
+
return undefined;
|
|
24
|
+
const target = routineNameFromExpression(item.instruction.expression);
|
|
25
|
+
if (target === undefined || target.startsWith('.'))
|
|
26
|
+
return undefined;
|
|
27
|
+
if (entryNames !== undefined && !entryNames.has(target))
|
|
28
|
+
return undefined;
|
|
29
|
+
return target;
|
|
30
|
+
}
|
|
16
31
|
function toInstruction(item, labels) {
|
|
17
32
|
return {
|
|
18
33
|
instruction: item.instruction,
|
|
@@ -22,9 +37,16 @@ function toInstruction(item, labels) {
|
|
|
22
37
|
labels: [...labels],
|
|
23
38
|
};
|
|
24
39
|
}
|
|
40
|
+
function pushDirectBoundary(boundaries, target, subject, file, line, column) {
|
|
41
|
+
boundaries.push({ target, subject, file, line, column });
|
|
42
|
+
}
|
|
25
43
|
export function buildRegisterCareProgramModel(items) {
|
|
26
44
|
const routines = [];
|
|
27
45
|
const directCalls = [];
|
|
46
|
+
const filesWithEntryLabels = new Set(items
|
|
47
|
+
.filter((item) => item.kind === 'label')
|
|
48
|
+
.filter((item) => item.isEntry === true)
|
|
49
|
+
.map((item) => item.span.sourceName));
|
|
28
50
|
let routineName;
|
|
29
51
|
let entryLabels = [];
|
|
30
52
|
let labels = [];
|
|
@@ -35,14 +57,28 @@ export function buildRegisterCareProgramModel(items) {
|
|
|
35
57
|
const startRoutine = (item) => {
|
|
36
58
|
sourceName = item.span.sourceName;
|
|
37
59
|
routineName = item.name;
|
|
38
|
-
entryLabels = [item.name];
|
|
60
|
+
entryLabels = item.isEntry === true ? [item.name] : [];
|
|
39
61
|
labels = [item.name];
|
|
40
62
|
routineStartLine = item.span.line;
|
|
41
63
|
routineStartColumn = item.span.column;
|
|
42
64
|
instructions = [];
|
|
43
65
|
};
|
|
44
66
|
const flushRoutine = () => {
|
|
45
|
-
if (routineName === undefined ||
|
|
67
|
+
if (routineName === undefined || routineStartLine === undefined) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (instructions.length === 0) {
|
|
71
|
+
routines.push({
|
|
72
|
+
name: routineName,
|
|
73
|
+
labels: [...labels],
|
|
74
|
+
entryLabels: [...entryLabels],
|
|
75
|
+
instructions: [],
|
|
76
|
+
span: {
|
|
77
|
+
file: sourceName ?? '',
|
|
78
|
+
start: { line: routineStartLine, column: routineStartColumn ?? 1 },
|
|
79
|
+
end: { line: routineStartLine, column: routineStartColumn ?? 1 },
|
|
80
|
+
},
|
|
81
|
+
});
|
|
46
82
|
return;
|
|
47
83
|
}
|
|
48
84
|
const end = instructions[instructions.length - 1];
|
|
@@ -88,12 +124,7 @@ export function buildRegisterCareProgramModel(items) {
|
|
|
88
124
|
instructions.push(toInstruction(item, labels));
|
|
89
125
|
const directTarget = instructionCallTarget(item);
|
|
90
126
|
if (directTarget !== undefined) {
|
|
91
|
-
directCalls.
|
|
92
|
-
target: directTarget,
|
|
93
|
-
file: item.span.sourceName,
|
|
94
|
-
line: item.span.line,
|
|
95
|
-
column: item.span.column,
|
|
96
|
-
});
|
|
127
|
+
pushDirectBoundary(directCalls, directTarget, `CALL ${directTarget}`, item.span.sourceName, item.span.line, item.span.column);
|
|
97
128
|
}
|
|
98
129
|
continue;
|
|
99
130
|
}
|
|
@@ -104,19 +135,54 @@ export function buildRegisterCareProgramModel(items) {
|
|
|
104
135
|
continue;
|
|
105
136
|
}
|
|
106
137
|
if (routineName === undefined) {
|
|
138
|
+
if (filesWithEntryLabels.has(item.span.sourceName) && item.isEntry !== true) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
107
141
|
startRoutine(item);
|
|
108
142
|
continue;
|
|
109
143
|
}
|
|
110
|
-
if (
|
|
111
|
-
|
|
112
|
-
|
|
144
|
+
if (sourceName === undefined || sourceName !== item.span.sourceName) {
|
|
145
|
+
finalizeAndRestart(item);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (instructions.length > 0) {
|
|
149
|
+
if (filesWithEntryLabels.has(item.span.sourceName) && item.isEntry !== true) {
|
|
150
|
+
labels.push(item.name);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
113
153
|
finalizeAndRestart(item);
|
|
114
154
|
continue;
|
|
115
155
|
}
|
|
116
156
|
// Multiple global labels before body on same routine are coalesced as entry labels.
|
|
117
157
|
labels.push(item.name);
|
|
118
|
-
|
|
158
|
+
if (item.isEntry === true) {
|
|
159
|
+
entryLabels.push(item.name);
|
|
160
|
+
}
|
|
119
161
|
}
|
|
120
162
|
flushRoutine();
|
|
121
|
-
|
|
163
|
+
const entryNamesByFile = new Map();
|
|
164
|
+
for (const item of items) {
|
|
165
|
+
if (item.kind !== 'label' || item.isEntry !== true)
|
|
166
|
+
continue;
|
|
167
|
+
const names = entryNamesByFile.get(item.span.sourceName) ?? new Set();
|
|
168
|
+
names.add(item.name);
|
|
169
|
+
entryNamesByFile.set(item.span.sourceName, names);
|
|
170
|
+
}
|
|
171
|
+
const directTailJumps = [];
|
|
172
|
+
for (const item of items) {
|
|
173
|
+
if (item.kind !== 'instruction')
|
|
174
|
+
continue;
|
|
175
|
+
const entryNames = filesWithEntryLabels.has(item.span.sourceName)
|
|
176
|
+
? entryNamesByFile.get(item.span.sourceName)
|
|
177
|
+
: undefined;
|
|
178
|
+
const target = instructionTailJumpTarget(item, entryNames);
|
|
179
|
+
if (target === undefined)
|
|
180
|
+
continue;
|
|
181
|
+
pushDirectBoundary(directTailJumps, target, `JP ${target}`, item.span.sourceName, item.span.line, item.span.column);
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
routines,
|
|
185
|
+
directCalls,
|
|
186
|
+
directBoundaries: [...directCalls, ...directTailJumps],
|
|
187
|
+
};
|
|
122
188
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { RegisterCareReportModel, RegisterCareUnit, RoutineSummary } from './types.js';
|
|
2
|
-
export declare function renderRegisterCareReport(model: RegisterCareReportModel): string;
|
|
3
2
|
export declare function contractCarrierList(units: RegisterCareUnit[]): string;
|
|
3
|
+
export declare function renderRegisterCareReport(model: RegisterCareReportModel): string;
|
|
4
4
|
export declare function renderRegisterCareInterface(summaries: RoutineSummary[]): string;
|
|
5
|
+
export declare function renderRegisterCareSourceBlock(summary: RoutineSummary): string[];
|
|
@@ -1,23 +1,94 @@
|
|
|
1
|
-
function
|
|
1
|
+
function list(units) {
|
|
2
2
|
return units.length === 0 ? '-' : units.join(',');
|
|
3
3
|
}
|
|
4
|
+
const FLAG_UNITS = new Set(['carry', 'zero', 'sign', 'parity', 'halfCarry']);
|
|
5
|
+
const CONTRACT_CARRIER_PAIRS = [
|
|
6
|
+
{ label: 'BC', hi: 'B', lo: 'C' },
|
|
7
|
+
{ label: 'DE', hi: 'D', lo: 'E' },
|
|
8
|
+
{ label: 'HL', hi: 'H', lo: 'L' },
|
|
9
|
+
{ label: 'IX', hi: 'IXH', lo: 'IXL' },
|
|
10
|
+
{ label: 'IY', hi: 'IYH', lo: 'IYL' },
|
|
11
|
+
{ label: 'SP', hi: 'SPH', lo: 'SPL' },
|
|
12
|
+
];
|
|
13
|
+
export function contractCarrierList(units) {
|
|
14
|
+
const unique = [...new Set(units)];
|
|
15
|
+
const unitSet = new Set(unique);
|
|
16
|
+
const emitted = new Set();
|
|
17
|
+
const parts = [];
|
|
18
|
+
for (const unit of unique) {
|
|
19
|
+
if (emitted.has(unit))
|
|
20
|
+
continue;
|
|
21
|
+
const pair = CONTRACT_CARRIER_PAIRS.find((candidate) => (candidate.hi === unit || candidate.lo === unit) &&
|
|
22
|
+
unitSet.has(candidate.hi) &&
|
|
23
|
+
unitSet.has(candidate.lo));
|
|
24
|
+
if (pair) {
|
|
25
|
+
parts.push(pair.label);
|
|
26
|
+
emitted.add(pair.hi);
|
|
27
|
+
emitted.add(pair.lo);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
parts.push(unit);
|
|
31
|
+
emitted.add(unit);
|
|
32
|
+
}
|
|
33
|
+
return parts.length === 0 ? '-' : parts.join(',');
|
|
34
|
+
}
|
|
35
|
+
function relationOutputUnits(relations) {
|
|
36
|
+
return relations.flatMap((rel) => rel.out);
|
|
37
|
+
}
|
|
38
|
+
function contractEntries(summary) {
|
|
39
|
+
const out = [];
|
|
40
|
+
if (summary.mayRead.length > 0)
|
|
41
|
+
out.push({ keyword: 'in', carriers: contractCarrierList(summary.mayRead) });
|
|
42
|
+
const outputUnits = relationOutputUnits(summary.valueRelations);
|
|
43
|
+
if (outputUnits.length > 0)
|
|
44
|
+
out.push({ keyword: 'out', carriers: contractCarrierList(outputUnits) });
|
|
45
|
+
const relationOut = relationOutUnits(summary);
|
|
46
|
+
const clobbers = summary.mayWrite.filter((unit) => !relationOut.has(unit));
|
|
47
|
+
if (clobbers.length > 0)
|
|
48
|
+
out.push({ keyword: 'clobbers', carriers: contractCarrierList(clobbers) });
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
function sourceContractEntries(summary) {
|
|
52
|
+
const out = [];
|
|
53
|
+
if (summary.mayRead.length > 0)
|
|
54
|
+
out.push({ keyword: 'in', carriers: contractCarrierList(summary.mayRead) });
|
|
55
|
+
const relationOut = relationOutUnits(summary);
|
|
56
|
+
const candidates = (summary.outputCandidates ?? []).filter((unit) => !relationOut.has(unit));
|
|
57
|
+
if (candidates.length > 0)
|
|
58
|
+
out.push({ keyword: 'maybe-out', carriers: contractCarrierList(candidates) });
|
|
59
|
+
const outputUnits = relationOutputUnits(summary.valueRelations);
|
|
60
|
+
if (outputUnits.length > 0)
|
|
61
|
+
out.push({ keyword: 'out', carriers: contractCarrierList(outputUnits) });
|
|
62
|
+
const clobbers = summary.mayWrite.filter((unit) => !relationOut.has(unit) && !FLAG_UNITS.has(unit));
|
|
63
|
+
if (clobbers.length > 0)
|
|
64
|
+
out.push({ keyword: 'clobbers', carriers: contractCarrierList(clobbers) });
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
function stackStatus(summary) {
|
|
68
|
+
const balance = summary.stackBalanced ? 'balanced' : 'unbalanced';
|
|
69
|
+
return summary.hasUnknownStackEffect ? `${balance}, unknown effect` : balance;
|
|
70
|
+
}
|
|
71
|
+
function relationOutUnits(summary) {
|
|
72
|
+
return new Set(summary.valueRelations.flatMap((rel) => rel.out));
|
|
73
|
+
}
|
|
4
74
|
export function renderRegisterCareReport(model) {
|
|
5
|
-
const lines = [
|
|
6
|
-
|
|
7
|
-
`
|
|
8
|
-
|
|
9
|
-
...(model.profile !== undefined ? [`Profile: ${model.profile}`] : []),
|
|
10
|
-
'',
|
|
11
|
-
];
|
|
75
|
+
const lines = ['AZM Register-Care Report', `Entry: ${model.entryFile}`, `Mode: ${model.mode}`];
|
|
76
|
+
if (model.profile)
|
|
77
|
+
lines.push(`Profile: ${model.profile}`);
|
|
78
|
+
lines.push('');
|
|
12
79
|
if (model.summaries.length === 0) {
|
|
13
80
|
lines.push('Routines: none', '');
|
|
14
81
|
}
|
|
15
82
|
else {
|
|
16
83
|
for (const summary of model.summaries) {
|
|
17
84
|
lines.push(`Routine: ${summary.name}`);
|
|
18
|
-
lines.push(` reads: ${
|
|
19
|
-
lines.push(` writes: ${
|
|
20
|
-
lines.push(` preserves: ${
|
|
85
|
+
lines.push(` reads: ${list(summary.mayRead)}`);
|
|
86
|
+
lines.push(` writes: ${list(summary.mayWrite)}`);
|
|
87
|
+
lines.push(` preserves: ${list(summary.preserved)}`);
|
|
88
|
+
lines.push(` stack: ${stackStatus(summary)}`);
|
|
89
|
+
for (const rel of summary.valueRelations) {
|
|
90
|
+
lines.push(` relation: ${list(rel.out)} <= ${list(rel.from)}`);
|
|
91
|
+
}
|
|
21
92
|
lines.push('');
|
|
22
93
|
}
|
|
23
94
|
}
|
|
@@ -27,17 +98,17 @@ export function renderRegisterCareReport(model) {
|
|
|
27
98
|
}
|
|
28
99
|
else {
|
|
29
100
|
for (const conflict of model.conflicts) {
|
|
30
|
-
lines.push(` ${conflict.file}:${conflict.line}:${conflict.column}: ${conflict.callTarget}: ${conflict.message}`);
|
|
101
|
+
lines.push(` ${conflict.file}:${conflict.line}:${conflict.column}: ${conflict.callTarget}: ${list(conflict.carriers)}: ${conflict.message}`);
|
|
31
102
|
}
|
|
32
103
|
}
|
|
33
104
|
lines.push('');
|
|
34
105
|
lines.push('Output candidates:');
|
|
35
|
-
if (model.outputCandidates
|
|
106
|
+
if (!model.outputCandidates || model.outputCandidates.length === 0) {
|
|
36
107
|
lines.push(' none');
|
|
37
108
|
}
|
|
38
109
|
else {
|
|
39
110
|
for (const candidate of model.outputCandidates) {
|
|
40
|
-
lines.push(` ${candidate.file}:${candidate.line}:${candidate.column}: ${candidate.routine}: ${candidate.carriers
|
|
111
|
+
lines.push(` ${candidate.file}:${candidate.line}:${candidate.column}: ${candidate.routine}: ${list(candidate.carriers)}: ${candidate.message}`);
|
|
41
112
|
}
|
|
42
113
|
}
|
|
43
114
|
lines.push('');
|
|
@@ -46,37 +117,23 @@ export function renderRegisterCareReport(model) {
|
|
|
46
117
|
lines.push(' none');
|
|
47
118
|
}
|
|
48
119
|
else {
|
|
49
|
-
for (const call of model.unknownCalls)
|
|
120
|
+
for (const call of model.unknownCalls)
|
|
50
121
|
lines.push(` ${call}`);
|
|
51
|
-
}
|
|
52
122
|
}
|
|
53
123
|
lines.push('');
|
|
54
124
|
return `${lines.join('\n')}\n`;
|
|
55
125
|
}
|
|
56
|
-
export function contractCarrierList(units) {
|
|
57
|
-
return units.length === 0 ? '-' : units.join(',');
|
|
58
|
-
}
|
|
59
126
|
export function renderRegisterCareInterface(summaries) {
|
|
60
127
|
const lines = [];
|
|
61
128
|
for (const summary of summaries) {
|
|
62
|
-
if (summary.mayRead.length === 0 &&
|
|
63
|
-
summary.mayWrite.length === 0 &&
|
|
64
|
-
summary.preserved.length === 0) {
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
129
|
lines.push(`extern ${summary.name}`);
|
|
68
|
-
|
|
69
|
-
lines.push(
|
|
70
|
-
}
|
|
71
|
-
if (summary.mayWrite.length > 0) {
|
|
72
|
-
lines.push(`clobbers ${contractCarrierList(summary.mayWrite)}`);
|
|
73
|
-
}
|
|
74
|
-
if (summary.preserved.length > 0) {
|
|
75
|
-
lines.push(`preserves ${contractCarrierList(summary.preserved)}`);
|
|
130
|
+
for (const entry of contractEntries(summary)) {
|
|
131
|
+
lines.push(`${entry.keyword} ${entry.carriers}`);
|
|
76
132
|
}
|
|
77
133
|
lines.push('end', '');
|
|
78
134
|
}
|
|
79
|
-
if (lines.length === 0)
|
|
80
|
-
lines.push('No inferred contracts were emitted.', '');
|
|
81
135
|
return `${lines.join('\n')}\n`;
|
|
82
136
|
}
|
|
137
|
+
export function renderRegisterCareSourceBlock(summary) {
|
|
138
|
+
return sourceContractEntries(summary).map((entry) => `;! ${entry.keyword.padEnd(10)}${entry.carriers}`);
|
|
139
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RegisterCareRoutine, RoutineContract, RoutineSummary } from './types.js';
|
|
2
|
+
export declare function summariesWithExternalContracts(summaries: RoutineSummary[], contracts: Map<string, RoutineContract>, routineNameSet: Set<string>): RoutineSummary[];
|
|
3
|
+
export declare function inferRoutineSummariesToFixedPoint(routines: RegisterCareRoutine[], contracts: Map<string, RoutineContract>, routineNameSet: Set<string>, profileSummaries: RoutineSummary[]): Array<{
|
|
4
|
+
routine: RegisterCareRoutine;
|
|
5
|
+
summary: RoutineSummary;
|
|
6
|
+
}>;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { applyRoutineContract, inferRoutineSummary } from './summary.js';
|
|
2
|
+
function emptyRoutineSummary(name) {
|
|
3
|
+
return {
|
|
4
|
+
name,
|
|
5
|
+
mayRead: [],
|
|
6
|
+
mayWrite: [],
|
|
7
|
+
preserved: [],
|
|
8
|
+
valueRelations: [],
|
|
9
|
+
stackBalanced: true,
|
|
10
|
+
hasUnknownStackEffect: false,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function isLocalLabel(name) {
|
|
14
|
+
return name.startsWith('.');
|
|
15
|
+
}
|
|
16
|
+
function nonLocalLabels(labels) {
|
|
17
|
+
return labels.filter((label) => !isLocalLabel(label));
|
|
18
|
+
}
|
|
19
|
+
function boundaryLabels(routine) {
|
|
20
|
+
return routine.entryLabels.length > 0 ? routine.entryLabels : nonLocalLabels(routine.labels);
|
|
21
|
+
}
|
|
22
|
+
function contractForRoutine(routine, contracts) {
|
|
23
|
+
return boundaryLabels(routine)
|
|
24
|
+
.map((label) => contracts.get(label))
|
|
25
|
+
.find((contract) => contract !== undefined);
|
|
26
|
+
}
|
|
27
|
+
export function summariesWithExternalContracts(summaries, contracts, routineNameSet) {
|
|
28
|
+
const out = [...summaries];
|
|
29
|
+
for (const contract of contracts.values()) {
|
|
30
|
+
if (!routineNameSet.has(contract.name)) {
|
|
31
|
+
out.push(applyRoutineContract(emptyRoutineSummary(contract.name), contract));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
function buildBoundarySummaryMap(summaries, routineSummaries, profileSummaries) {
|
|
37
|
+
const boundarySummaryMap = new Map(profileSummaries.map((summary) => [summary.name, summary]));
|
|
38
|
+
for (const summary of summaries) {
|
|
39
|
+
boundarySummaryMap.set(summary.name, summary);
|
|
40
|
+
}
|
|
41
|
+
for (const { routine, summary } of routineSummaries) {
|
|
42
|
+
for (const label of boundaryLabels(routine)) {
|
|
43
|
+
boundarySummaryMap.set(label, summary);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return boundarySummaryMap;
|
|
47
|
+
}
|
|
48
|
+
function summarizeRoutines(routines, contracts, boundarySummaryMap = new Map()) {
|
|
49
|
+
return routines.map((routine) => {
|
|
50
|
+
const inferred = inferRoutineSummary(routine, boundarySummaryMap);
|
|
51
|
+
const contract = contractForRoutine(routine, contracts);
|
|
52
|
+
return { routine, summary: contract ? applyRoutineContract(inferred, contract) : inferred };
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function sortedUnique(values) {
|
|
56
|
+
return Array.from(new Set(values)).sort();
|
|
57
|
+
}
|
|
58
|
+
function summaryFingerprint(summary) {
|
|
59
|
+
const relations = summary.valueRelations
|
|
60
|
+
.map((relation) => `${relation.out.join(',')}<-${relation.from.join(',')}`)
|
|
61
|
+
.sort();
|
|
62
|
+
return JSON.stringify({
|
|
63
|
+
name: summary.name,
|
|
64
|
+
mayRead: sortedUnique(summary.mayRead),
|
|
65
|
+
mayWrite: sortedUnique(summary.mayWrite),
|
|
66
|
+
preserved: sortedUnique(summary.preserved),
|
|
67
|
+
relations,
|
|
68
|
+
stackBalanced: summary.stackBalanced,
|
|
69
|
+
hasUnknownStackEffect: summary.hasUnknownStackEffect,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function routineSummariesFingerprint(routineSummaries) {
|
|
73
|
+
return routineSummaries.map((item) => summaryFingerprint(item.summary)).join('\n');
|
|
74
|
+
}
|
|
75
|
+
export function inferRoutineSummariesToFixedPoint(routines, contracts, routineNameSet, profileSummaries) {
|
|
76
|
+
let routineSummaries = summarizeRoutines(routines, contracts);
|
|
77
|
+
const maxPasses = Math.max(2, routines.length + 2);
|
|
78
|
+
for (let pass = 0; pass < maxPasses; pass += 1) {
|
|
79
|
+
const summaries = summariesWithExternalContracts(routineSummaries.map((item) => item.summary), contracts, routineNameSet);
|
|
80
|
+
const boundarySummaryMap = buildBoundarySummaryMap(summaries, routineSummaries, profileSummaries);
|
|
81
|
+
const nextRoutineSummaries = summarizeRoutines(routines, contracts, boundarySummaryMap);
|
|
82
|
+
if (routineSummariesFingerprint(nextRoutineSummaries) ===
|
|
83
|
+
routineSummariesFingerprint(routineSummaries)) {
|
|
84
|
+
return nextRoutineSummaries;
|
|
85
|
+
}
|
|
86
|
+
routineSummaries = nextRoutineSummaries;
|
|
87
|
+
}
|
|
88
|
+
return routineSummaries;
|
|
89
|
+
}
|
|
@@ -3,10 +3,10 @@ import type { AnalyzeRegisterCareOptions, RegisterCareDirectCall, RegisterCareRo
|
|
|
3
3
|
export declare function buildProfileSummaries(profileName: AnalyzeRegisterCareOptions['registerCareProfile']): RoutineSummary[];
|
|
4
4
|
export declare function buildProfileSummaryLookup(profileName: AnalyzeRegisterCareOptions['registerCareProfile']): Map<string, RoutineSummary>;
|
|
5
5
|
export declare function routineNames(routines: readonly RegisterCareRoutine[]): string[];
|
|
6
|
-
export declare function buildSummaries(routines: readonly RegisterCareRoutine[], contractMap: Map<string, RoutineContract
|
|
6
|
+
export declare function buildSummaries(routines: readonly RegisterCareRoutine[], contractMap: Map<string, RoutineContract>, profileSummaries?: readonly RoutineSummary[]): RoutineSummary[];
|
|
7
7
|
export declare function buildSummaryByName(routines: readonly RegisterCareRoutine[], summaries: readonly RoutineSummary[], profileSummaries?: readonly RoutineSummary[]): Map<string, RoutineSummary>;
|
|
8
8
|
export declare function withAcceptedOutputs(summaries: readonly RoutineSummary[], acceptedOutputCandidates: ReadonlyMap<string, RegisterCareUnit[]> | undefined): RoutineSummary[];
|
|
9
|
-
export declare function unknownBoundaryDiagnostics(
|
|
10
|
-
export declare function unknownCallList(
|
|
9
|
+
export declare function unknownBoundaryDiagnostics(directBoundaries: readonly RegisterCareDirectCall[], knownRoutines: ReadonlySet<string>): Diagnostic[];
|
|
10
|
+
export declare function unknownCallList(directBoundaries: readonly RegisterCareDirectCall[], knownRoutines: ReadonlySet<string>): string[];
|
|
11
11
|
export declare function buildOutputCandidateFixability(routines: readonly RegisterCareRoutine[], outputCandidates: readonly RegisterCareOutputCandidate[], autoFixableCandidateKeys: (routines: RegisterCareRoutine[], outputCandidates: RegisterCareOutputCandidate[]) => ReadonlySet<string>): ReadonlyMap<string, boolean>;
|
|
12
12
|
export declare function outputCandidateKey(file: string, line: number, column: number): string;
|