@asmlift/core 0.8.1 → 0.10.0

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.
Files changed (130) hide show
  1. package/README.md +36 -31
  2. package/package.json +1 -1
  3. package/src/aggregate.ts +397 -0
  4. package/src/backend/c.ts +6 -2
  5. package/src/backend/cfamily.ts +370 -56
  6. package/src/backend/cpp.ts +116 -10
  7. package/src/backend/pascal.ts +69 -11
  8. package/src/cdecl/constant.ts +59 -0
  9. package/src/cdecl/lex.ts +209 -0
  10. package/src/cdecl/parse.ts +975 -0
  11. package/src/cdecl/spell.ts +69 -0
  12. package/src/codegen-flags.ts +38 -6
  13. package/src/compiler-diagnostics.ts +194 -0
  14. package/src/contracts.ts +777 -84
  15. package/src/declare.ts +132 -13
  16. package/src/frontend/asmdata.ts +26 -6
  17. package/src/frontend/call-plan.ts +1590 -0
  18. package/src/frontend/dead-reads.ts +628 -0
  19. package/src/frontend/device-pins.ts +296 -0
  20. package/src/frontend/emit.ts +4 -3
  21. package/src/frontend/errors.ts +5 -0
  22. package/src/frontend/flags-edge.ts +101 -0
  23. package/src/frontend/fpu.ts +374 -0
  24. package/src/frontend/frame-objects.ts +3171 -0
  25. package/src/frontend/frontend.ts +64 -3
  26. package/src/frontend/high-half.ts +55 -5
  27. package/src/frontend/jump-table.ts +530 -0
  28. package/src/frontend/local-object.ts +616 -0
  29. package/src/frontend/mips.ts +2392 -208
  30. package/src/frontend/opaque.ts +97 -18
  31. package/src/frontend/own-struct-return.ts +500 -0
  32. package/src/frontend/ppc.ts +3137 -267
  33. package/src/frontend/register-struct-call.ts +484 -0
  34. package/src/frontend/reloc-symbol.ts +109 -13
  35. package/src/frontend/splat.ts +108 -5
  36. package/src/frontend/ssa.ts +2098 -89
  37. package/src/frontend/stackargs.ts +172 -42
  38. package/src/frontend/thumb.ts +4563 -2091
  39. package/src/ir/alias.ts +71 -0
  40. package/src/ir/bits.ts +681 -1
  41. package/src/ir/core.ts +199 -6
  42. package/src/ir/discipline.ts +313 -0
  43. package/src/ir/entry.ts +159 -0
  44. package/src/ir/float-bits.ts +47 -0
  45. package/src/{structure → ir}/loops.ts +6 -2
  46. package/src/ir/opcodes.ts +193 -121
  47. package/src/ir/parse.ts +1 -0
  48. package/src/ir/types.ts +202 -2
  49. package/src/ir/verify.ts +219 -3
  50. package/src/l3/address.ts +5 -0
  51. package/src/l3/argcopy.ts +38 -6
  52. package/src/l3/ast.ts +467 -23
  53. package/src/l3/basecse.ts +33 -5
  54. package/src/l3/coalesce.ts +21 -13
  55. package/src/l3/constinit.ts +382 -0
  56. package/src/l3/dce.ts +34 -12
  57. package/src/l3/gates.ts +9 -3
  58. package/src/l3/hoist.ts +8 -7
  59. package/src/l3/initfirst.ts +68 -19
  60. package/src/l3/intcell.ts +98 -0
  61. package/src/l3/mentions.ts +10 -4
  62. package/src/l3/narrowdecl.ts +259 -0
  63. package/src/l3/nearbase.ts +10 -5
  64. package/src/l3/parkfirst.ts +8 -5
  65. package/src/l3/pollguard.ts +11 -4
  66. package/src/l3/ptrcell.ts +354 -0
  67. package/src/l3/ptrfield.ts +123 -8
  68. package/src/l3/regspell.ts +26 -7
  69. package/src/l3/reindex.ts +293 -103
  70. package/src/l3/storage.ts +98 -1
  71. package/src/l3/symbol-refs.ts +182 -23
  72. package/src/l3/tailmerge.ts +9 -20
  73. package/src/l3/typing.ts +237 -32
  74. package/src/l3/unreduce.ts +10 -9
  75. package/src/l3/volatileptr.ts +17 -54
  76. package/src/l3/volstore.ts +96 -7
  77. package/src/mangle.ts +41 -1
  78. package/src/pattern/engine.ts +373 -82
  79. package/src/pipeline.ts +589 -27
  80. package/src/proto-context.ts +1648 -0
  81. package/src/proto.ts +1203 -49
  82. package/src/raise/aggmembers.ts +290 -0
  83. package/src/raise/arrays.ts +8 -3
  84. package/src/raise/declared-volatile.ts +307 -0
  85. package/src/raise/divpow2.ts +2 -2
  86. package/src/raise/errors.ts +17 -0
  87. package/src/raise/floathelpers.ts +464 -0
  88. package/src/raise/globalshape.ts +11 -5
  89. package/src/raise/gvn.ts +29 -8
  90. package/src/raise/latch.ts +162 -6
  91. package/src/raise/memberarrays.ts +10 -4
  92. package/src/raise/narrow.ts +29 -2
  93. package/src/raise/narrowlocal.ts +11 -6
  94. package/src/raise/offsetnames.ts +494 -0
  95. package/src/raise/pairparams.ts +114 -0
  96. package/src/raise/paramwidth.ts +203 -6
  97. package/src/raise/pre-recovery.ts +174 -17
  98. package/src/raise/pre-structure.ts +54 -0
  99. package/src/raise/recover.ts +26 -15
  100. package/src/raise/reroll.ts +694 -0
  101. package/src/raise/retsink.ts +1 -1
  102. package/src/raise/shortcircuit.ts +66 -30
  103. package/src/raise/softdiv.ts +21 -23
  104. package/src/raise/storesign.ts +153 -0
  105. package/src/raise/struct-arrays.ts +34 -14
  106. package/src/raise/structs.ts +674 -98
  107. package/src/raise/truncload.ts +367 -0
  108. package/src/raise/unthread.ts +400 -0
  109. package/src/raise/widehelpers.ts +106 -0
  110. package/src/rank-declare.ts +143 -12
  111. package/src/rank-variations.ts +117 -31
  112. package/src/rank.ts +563 -122
  113. package/src/runtime-helpers.ts +405 -0
  114. package/src/stillborn.ts +289 -0
  115. package/src/structure/analysis.ts +1449 -449
  116. package/src/structure/arith-ops.ts +23 -0
  117. package/src/structure/globalaccess.ts +111 -9
  118. package/src/structure/hazards.ts +641 -114
  119. package/src/structure/local-statics.ts +517 -0
  120. package/src/structure/namecoalesce.ts +2 -2
  121. package/src/structure/pointer-spelling.ts +1106 -0
  122. package/src/structure/redundant-test.ts +99 -0
  123. package/src/structure/structure.ts +3478 -975
  124. package/src/structure/switch-recover.ts +403 -178
  125. package/src/symbols.ts +44 -3
  126. package/src/target.ts +1387 -71
  127. package/src/trace.ts +66 -28
  128. package/src/variation-definitions.ts +243 -13
  129. package/src/variation-gates.ts +2 -0
  130. package/src/variation-tokens.ts +25 -7
package/src/symbols.ts CHANGED
@@ -189,6 +189,12 @@ export interface SymbolInfo {
189
189
  * DECLARATION differs — `#define name body` instead of `extern T name;` — which is why the
190
190
  * body is carried rather than reconstructed. */
191
191
  macroBody?: string;
192
+ /** This name is a FILE-SCOPE GLOBAL REGISTER VARIABLE, and this is the register's `__asm__` name
193
+ * (`target.globalRegisterVariables`): the lift reads and writes a callee-saved register no
194
+ * prologue saved as this global. `gName` and `gName = v` mean what they mean for an `extern`, and
195
+ * `&gName` is an error, as for any register variable. Only the DECLARATION differs —
196
+ * `register T name __asm__("r8");` instead of `extern T name;`. */
197
+ globalRegister?: string;
192
198
  }
193
199
 
194
200
  /** THE one reading of {@link SymbolInfo.dims} for spelling C, shared by the access side
@@ -268,6 +274,27 @@ export function isBitfieldField(f: SymbolStructField): boolean {
268
274
  return f.bitWidth !== undefined;
269
275
  }
270
276
 
277
+ /** Does this declaration make an access at `byte` of the object volatile? The object's own
278
+ * qualifier answers for every byte. A qualified MEMBER answers only for the bytes it spans — the
279
+ * `vu16 field;` idiom puts one in a struct whose other members are ordinary cells — and one of
280
+ * unknown extent spans whatever follows it. `null` is an access whose offset is not pinned, which
281
+ * may reach any member, so only a layout whose every member is qualified answers it. A member this
282
+ * module cannot read (`SymbolMap` is caller-supplied) qualifies nothing. */
283
+ export function declaresVolatile(info: SymbolInfo | undefined, byte: number | null): boolean {
284
+ if (info?.volatile === true) {
285
+ return true;
286
+ }
287
+ const layout: unknown = info?.layout;
288
+ if (!Array.isArray(layout) || layout.length === 0) {
289
+ return false;
290
+ }
291
+ const qualified = (f: unknown): f is SymbolStructField => wellFormedField(f) && f.volatile === true;
292
+ if (byte === null) {
293
+ return layout.every(qualified);
294
+ }
295
+ return layout.some((f) => qualified(f) && byte >= f.offset && (f.size === null || byte < f.offset + f.size));
296
+ }
297
+
271
298
  /** Does the map declare a bitfield member anywhere, in a symbol's own layout or its pointee's? */
272
299
  export function declaresBitfields(symbols: SymbolMap): boolean {
273
300
  return [...symbols.values()].some((infos) =>
@@ -494,6 +521,16 @@ export function isScalarCellSize(size: number | undefined): size is 1 | 2 | 4 {
494
521
  return size === 1 || size === 2 || size === 4;
495
522
  }
496
523
 
524
+ /** THE SIGNEDNESS AN ACCESS OF THIS WIDTH STATES. A sub-word load says in the instruction whether
525
+ * it sign- or zero-fills; a whole-word one performs no extension at all, so whatever `signed`
526
+ * its attrs carry says nothing about the cell. Every comparison between an access and a
527
+ * declaration normalizes both sides through here — `rank-declare.ts`'s `bareGlobalAccessFacts`
528
+ * for a bare name over a whole function, `raise/offsetnames.ts` for the accesses made through one
529
+ * address — or a 4-byte load's incidental attr decides a declaration. */
530
+ export function accessSignedness(width: number, signed: boolean | undefined): boolean {
531
+ return signed === true && width < 4;
532
+ }
533
+
497
534
  /** THE DECLARED type of a 1/2/4-byte scalar cell — what `extern T gSym;` synthesis writes, and
498
535
  * therefore what `&gSym` actually points to.
499
536
  *
@@ -625,8 +662,9 @@ function factsOf(info: SymbolInfo): string {
625
662
  );
626
663
  }
627
664
 
628
- /** NAME-keyed view over every symbol in the map — what the structurer consumes (it sees gaddr
629
- * symbol names, not addresses). Aliases at one address each appear under their own name.
665
+ /** NAME-keyed view over every symbol in the map, or over the names in `only` — what the structurer
666
+ * consumes (it sees gaddr symbol names, not addresses). Aliases at one address each appear under
667
+ * their own name.
630
668
  *
631
669
  * One name can sit at SEVERAL addresses in a real project (file-static `sMenu` in two
632
670
  * translation units, a `.symtab` full of same-named locals). Where those entries agree on their
@@ -639,11 +677,14 @@ function factsOf(info: SymbolInfo): string {
639
677
  * spelling question into a compile failure); only the shape facts, which are what could be wrong,
640
678
  * are withheld — the honest cast spellings take over. `kind` is kept: it never disagrees in the
641
679
  * vendored maps, and it is settled address-side by `lookupSymbol` before a name is ever used. */
642
- export function symbolsByName(map: SymbolMap): Map<string, SymbolInfo> {
680
+ export function symbolsByName(map: SymbolMap, only?: ReadonlySet<string>): Map<string, SymbolInfo> {
643
681
  const byName = new Map<string, SymbolInfo>();
644
682
  const conflicted = new Set<string>();
645
683
  for (const infos of map.values()) {
646
684
  for (const info of infos) {
685
+ if (only !== undefined && !only.has(info.name)) {
686
+ continue;
687
+ }
647
688
  const prev = byName.get(info.name);
648
689
  if (prev === undefined) {
649
690
  byName.set(info.name, info);