psyq-asm 0.0.1

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 (117) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/LICENSE +56 -0
  3. package/README.md +220 -0
  4. package/bin/psyq-asm.mjs +149 -0
  5. package/dist/asm/assemble.d.ts +10 -0
  6. package/dist/asm/assemble.d.ts.map +1 -0
  7. package/dist/asm/assemble.js +42 -0
  8. package/dist/asm/assemble.js.map +1 -0
  9. package/dist/asm/diagnostics.d.ts +22 -0
  10. package/dist/asm/diagnostics.d.ts.map +1 -0
  11. package/dist/asm/diagnostics.js +40 -0
  12. package/dist/asm/diagnostics.js.map +1 -0
  13. package/dist/asm/directives.d.ts +67 -0
  14. package/dist/asm/directives.d.ts.map +1 -0
  15. package/dist/asm/directives.js +254 -0
  16. package/dist/asm/directives.js.map +1 -0
  17. package/dist/asm/expand.d.ts +21 -0
  18. package/dist/asm/expand.d.ts.map +1 -0
  19. package/dist/asm/expand.js +540 -0
  20. package/dist/asm/expand.js.map +1 -0
  21. package/dist/asm/hazards.d.ts +10 -0
  22. package/dist/asm/hazards.d.ts.map +1 -0
  23. package/dist/asm/hazards.js +196 -0
  24. package/dist/asm/hazards.js.map +1 -0
  25. package/dist/asm/layout.d.ts +17 -0
  26. package/dist/asm/layout.d.ts.map +1 -0
  27. package/dist/asm/layout.js +257 -0
  28. package/dist/asm/layout.js.map +1 -0
  29. package/dist/asm/lexer.d.ts +23 -0
  30. package/dist/asm/lexer.d.ts.map +1 -0
  31. package/dist/asm/lexer.js +81 -0
  32. package/dist/asm/lexer.js.map +1 -0
  33. package/dist/asm/object.d.ts +6 -0
  34. package/dist/asm/object.d.ts.map +1 -0
  35. package/dist/asm/object.js +46 -0
  36. package/dist/asm/object.js.map +1 -0
  37. package/dist/asm/operands.d.ts +49 -0
  38. package/dist/asm/operands.d.ts.map +1 -0
  39. package/dist/asm/operands.js +114 -0
  40. package/dist/asm/operands.js.map +1 -0
  41. package/dist/asm/parser.d.ts +28 -0
  42. package/dist/asm/parser.d.ts.map +1 -0
  43. package/dist/asm/parser.js +60 -0
  44. package/dist/asm/parser.js.map +1 -0
  45. package/dist/asm/relocations.d.ts +42 -0
  46. package/dist/asm/relocations.d.ts.map +1 -0
  47. package/dist/asm/relocations.js +214 -0
  48. package/dist/asm/relocations.js.map +1 -0
  49. package/dist/asm/sections.d.ts +23 -0
  50. package/dist/asm/sections.d.ts.map +1 -0
  51. package/dist/asm/sections.js +81 -0
  52. package/dist/asm/sections.js.map +1 -0
  53. package/dist/asm/stream.d.ts +77 -0
  54. package/dist/asm/stream.d.ts.map +1 -0
  55. package/dist/asm/stream.js +2 -0
  56. package/dist/asm/stream.js.map +1 -0
  57. package/dist/asm/symbols.d.ts +42 -0
  58. package/dist/asm/symbols.d.ts.map +1 -0
  59. package/dist/asm/symbols.js +122 -0
  60. package/dist/asm/symbols.js.map +1 -0
  61. package/dist/errors.d.ts +27 -0
  62. package/dist/errors.d.ts.map +1 -0
  63. package/dist/errors.js +34 -0
  64. package/dist/errors.js.map +1 -0
  65. package/dist/index.d.ts +14 -0
  66. package/dist/index.d.ts.map +1 -0
  67. package/dist/index.js +10 -0
  68. package/dist/index.js.map +1 -0
  69. package/dist/isa/decode.d.ts +8 -0
  70. package/dist/isa/decode.d.ts.map +1 -0
  71. package/dist/isa/decode.js +92 -0
  72. package/dist/isa/decode.js.map +1 -0
  73. package/dist/isa/encode.d.ts +9 -0
  74. package/dist/isa/encode.d.ts.map +1 -0
  75. package/dist/isa/encode.js +124 -0
  76. package/dist/isa/encode.js.map +1 -0
  77. package/dist/isa/fields.d.ts +27 -0
  78. package/dist/isa/fields.d.ts.map +1 -0
  79. package/dist/isa/fields.js +49 -0
  80. package/dist/isa/fields.js.map +1 -0
  81. package/dist/isa/format.d.ts +14 -0
  82. package/dist/isa/format.d.ts.map +1 -0
  83. package/dist/isa/format.js +98 -0
  84. package/dist/isa/format.js.map +1 -0
  85. package/dist/isa/instruction.d.ts +15 -0
  86. package/dist/isa/instruction.d.ts.map +1 -0
  87. package/dist/isa/instruction.js +47 -0
  88. package/dist/isa/instruction.js.map +1 -0
  89. package/dist/isa/registers.d.ts +8 -0
  90. package/dist/isa/registers.d.ts.map +1 -0
  91. package/dist/isa/registers.js +55 -0
  92. package/dist/isa/registers.js.map +1 -0
  93. package/dist/isa/table.d.ts +179 -0
  94. package/dist/isa/table.d.ts.map +1 -0
  95. package/dist/isa/table.js +128 -0
  96. package/dist/isa/table.js.map +1 -0
  97. package/dist/options.d.ts +29 -0
  98. package/dist/options.d.ts.map +1 -0
  99. package/dist/options.js +0 -0
  100. package/dist/options.js.map +1 -0
  101. package/dist/program/decode-words.d.ts +9 -0
  102. package/dist/program/decode-words.d.ts.map +1 -0
  103. package/dist/program/decode-words.js +87 -0
  104. package/dist/program/decode-words.js.map +1 -0
  105. package/dist/program/format-program.d.ts +12 -0
  106. package/dist/program/format-program.d.ts.map +1 -0
  107. package/dist/program/format-program.js +37 -0
  108. package/dist/program/format-program.js.map +1 -0
  109. package/dist/public-types.d.ts +253 -0
  110. package/dist/public-types.d.ts.map +1 -0
  111. package/dist/public-types.js +2 -0
  112. package/dist/public-types.js.map +1 -0
  113. package/dist/util.d.ts +3 -0
  114. package/dist/util.d.ts.map +1 -0
  115. package/dist/util.js +11 -0
  116. package/dist/util.js.map +1 -0
  117. package/package.json +82 -0
@@ -0,0 +1,81 @@
1
+ /** `.text` holds code; `.bss` and `.sbss` reserve space; everything else is data. */
2
+ export function sectionKind(name) {
3
+ if (name === '.text')
4
+ return 'code';
5
+ if (name === '.bss' || name === '.sbss')
6
+ return 'bss';
7
+ return 'data';
8
+ }
9
+ /** Accumulates one section's contents during layout. */
10
+ export class SectionBuilder {
11
+ name;
12
+ kind;
13
+ relocations = [];
14
+ data = [];
15
+ origins = [];
16
+ reserved = 0;
17
+ constructor(name) {
18
+ this.name = name;
19
+ this.kind = sectionKind(name);
20
+ }
21
+ /** The current size, in bytes. */
22
+ get offset() {
23
+ return this.kind === 'bss' ? this.reserved : this.data.length;
24
+ }
25
+ pushWord(word, origin) {
26
+ this.data.push(word & 0xff, (word >>> 8) & 0xff, (word >>> 16) & 0xff, word >>> 24);
27
+ this.origins.push(origin);
28
+ }
29
+ pushBytes(bytes, origin) {
30
+ for (const byte of bytes)
31
+ this.data.push(byte);
32
+ this.coverWithOrigin(origin);
33
+ }
34
+ /** Reserve zeroed space: nop words where code is word-aligned, zero bytes otherwise. */
35
+ pad(size, origin) {
36
+ if (this.kind === 'bss') {
37
+ this.reserved += size;
38
+ return;
39
+ }
40
+ let remaining = size;
41
+ if (this.kind === 'code' && this.data.length % 4 === 0) {
42
+ for (; remaining >= 4; remaining -= 4)
43
+ this.pushWord(0, origin);
44
+ }
45
+ this.pushBytes(new Uint8Array(remaining), origin);
46
+ }
47
+ coverWithOrigin(origin) {
48
+ if (this.kind !== 'code')
49
+ return;
50
+ while (this.origins.length * 4 < this.data.length)
51
+ this.origins.push(origin);
52
+ }
53
+ finish() {
54
+ if (this.kind === 'code') {
55
+ while (this.data.length % 4 !== 0)
56
+ this.data.push(0);
57
+ const bytes = Uint8Array.from(this.data);
58
+ const view = new DataView(bytes.buffer);
59
+ const words = new Uint32Array(bytes.length / 4);
60
+ for (let i = 0; i < words.length; i++)
61
+ words[i] = view.getUint32(i * 4, true);
62
+ return {
63
+ name: this.name,
64
+ kind: this.kind,
65
+ bytes,
66
+ size: bytes.length,
67
+ words,
68
+ relocations: this.relocations,
69
+ provenance: this.origins,
70
+ };
71
+ }
72
+ return {
73
+ name: this.name,
74
+ kind: this.kind,
75
+ bytes: Uint8Array.from(this.data),
76
+ size: this.offset,
77
+ relocations: this.relocations,
78
+ };
79
+ }
80
+ }
81
+ //# sourceMappingURL=sections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sections.js","sourceRoot":"","sources":["../../src/asm/sections.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * The expanded stream: what the expansion pass produces, the nop pass edits,
3
+ * and the layout pass encodes. Instructions become groups of pending words
4
+ * whose symbolic operands are resolved only at layout.
5
+ */
6
+ import type { Slot } from '../isa/fields.js';
7
+ import type { IsaRow } from '../isa/table.js';
8
+ import type { WordOriginKind } from '../public-types.js';
9
+ import type { Directive } from './directives.js';
10
+ import type { Expr } from './operands.js';
11
+ /** An operand whose value may still depend on symbols or label addresses. */
12
+ export type Pending = {
13
+ readonly kind: 'gpr';
14
+ readonly number: number;
15
+ } | {
16
+ readonly kind: 'cop';
17
+ readonly number: number;
18
+ readonly unit: 0 | 2;
19
+ readonly space: 'data' | 'control';
20
+ }
21
+ /** Immediates, shift amounts, codes, and jump targets. */
22
+ | {
23
+ readonly kind: 'value';
24
+ readonly expr: Expr;
25
+ } | {
26
+ readonly kind: 'mem';
27
+ readonly base: number;
28
+ readonly offset: Expr;
29
+ } | {
30
+ readonly kind: 'branch';
31
+ readonly target: Expr;
32
+ };
33
+ export interface PendingArg {
34
+ readonly slot: Slot;
35
+ readonly value: Pending;
36
+ }
37
+ export interface PendingWord {
38
+ readonly row: IsaRow;
39
+ readonly args: readonly PendingArg[];
40
+ readonly origin: WordOriginKind;
41
+ readonly note?: string;
42
+ }
43
+ /** The words one source statement became. */
44
+ export interface Group {
45
+ readonly kind: 'group';
46
+ readonly line: number;
47
+ readonly column: number;
48
+ readonly section: string;
49
+ /** Whether `.set reorder` was in effect. */
50
+ readonly reorder: boolean;
51
+ readonly words: readonly PendingWord[];
52
+ /** The macro mnemonic, when the statement expanded. */
53
+ readonly macro?: string;
54
+ /** For a `div`/`rem` expansion, the register its final `mflo`/`mfhi` writes. */
55
+ readonly divMove?: number;
56
+ }
57
+ export type Item = Group | {
58
+ readonly kind: 'label';
59
+ readonly name: string;
60
+ readonly line: number;
61
+ readonly column: number;
62
+ readonly transparent: boolean;
63
+ }
64
+ /** `.set` options: never end the nop pass's lookahead. */
65
+ | {
66
+ readonly kind: 'set';
67
+ readonly option: string;
68
+ readonly line: number;
69
+ }
70
+ /** Any other directive: ends the nop pass's lookahead. */
71
+ | {
72
+ readonly kind: 'directive';
73
+ readonly directive: Directive;
74
+ readonly line: number;
75
+ readonly column: number;
76
+ };
77
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/asm/stream.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/asm/stream.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ /** Pass 1: symbol definitions, bindings, common and extern sizes, and small data. */
2
+ import type { SmallDataEntry } from '../public-types.js';
3
+ import type { Diagnostics } from './diagnostics.js';
4
+ import type { Statement } from './parser.js';
5
+ export interface CommonSymbol {
6
+ readonly name: string;
7
+ readonly size: number;
8
+ readonly align: number | undefined;
9
+ readonly local: boolean;
10
+ }
11
+ export interface SymbolTable {
12
+ /** Every symbol and label name, in order of first appearance. */
13
+ readonly order: readonly string[];
14
+ /** Labels by name, with the section they were defined in. */
15
+ readonly labels: ReadonlyMap<string, {
16
+ readonly section: string;
17
+ readonly line: number;
18
+ }>;
19
+ readonly globals: ReadonlySet<string>;
20
+ readonly externs: ReadonlyMap<string, number | undefined>;
21
+ readonly commons: ReadonlyMap<string, CommonSymbol>;
22
+ }
23
+ /**
24
+ * Compiler-generated labels that are not symbols: `$L12`, `$LC0`, and `L`
25
+ * followed by a non-digit (`LM439`, debugging line markers). They are resolved
26
+ * against their section rather than exported.
27
+ */
28
+ export declare function isLocalLabel(name: string): boolean;
29
+ /**
30
+ * Labels the nop pass looks past, as maspsx does: numbered code labels (`$L12`,
31
+ * `$Lb3`, `$Le3`) and `L`-plus-non-digit markers. Any other label ends the
32
+ * lookahead.
33
+ */
34
+ export declare function isTransparentLabel(name: string): boolean;
35
+ export declare function collectSymbols(statements: readonly Statement[], diagnostics: Diagnostics): SymbolTable;
36
+ /**
37
+ * The symbols ASPSX addresses through `$gp` at this -G value: labels in
38
+ * `.sdata`/`.sbss`, commons no larger than the threshold, and (only with
39
+ * `experimental.externSmallData`) externs declared no larger than it.
40
+ */
41
+ export declare function classifySmallData(table: SymbolTable, gpSize: number, externSmallData: boolean): Map<string, SmallDataEntry>;
42
+ //# sourceMappingURL=symbols.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../../src/asm/symbols.ts"],"names":[],"mappings":"AACA,qFAAqF;AACrF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1F,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAC1D,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACrD;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,cAAc,CAC5B,UAAU,EAAE,SAAS,SAAS,EAAE,EAChC,WAAW,EAAE,WAAW,GACvB,WAAW,CA8Eb;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,OAAO,GACvB,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAmB7B"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Compiler-generated labels that are not symbols: `$L12`, `$LC0`, and `L`
3
+ * followed by a non-digit (`LM439`, debugging line markers). They are resolved
4
+ * against their section rather than exported.
5
+ */
6
+ export function isLocalLabel(name) {
7
+ return name.startsWith('$L') || /^L[^0-9]/.test(name);
8
+ }
9
+ /**
10
+ * Labels the nop pass looks past, as maspsx does: numbered code labels (`$L12`,
11
+ * `$Lb3`, `$Le3`) and `L`-plus-non-digit markers. Any other label ends the
12
+ * lookahead.
13
+ */
14
+ export function isTransparentLabel(name) {
15
+ return /^\$L[be]?\d+$/.test(name) || /^L[^0-9]/.test(name);
16
+ }
17
+ export function collectSymbols(statements, diagnostics) {
18
+ const order = [];
19
+ const seen = new Set();
20
+ const labels = new Map();
21
+ const globals = new Set();
22
+ const externs = new Map();
23
+ const commons = new Map();
24
+ let section = '.text';
25
+ const note = (name) => {
26
+ if (seen.has(name))
27
+ return;
28
+ seen.add(name);
29
+ order.push(name);
30
+ };
31
+ const noteExpr = (expr) => {
32
+ if (expr.kind === 'symbol')
33
+ note(expr.name);
34
+ else if (expr.kind === 'reloc' && expr.inner.kind === 'symbol')
35
+ note(expr.inner.name);
36
+ };
37
+ for (const statement of statements) {
38
+ switch (statement.kind) {
39
+ case 'label': {
40
+ const previous = labels.get(statement.name);
41
+ if (previous !== undefined) {
42
+ diagnostics.error(statement, 'duplicate-label', `${statement.name} is already defined on line ${String(previous.line)}.`);
43
+ }
44
+ else {
45
+ labels.set(statement.name, { section, line: statement.line });
46
+ }
47
+ note(statement.name);
48
+ break;
49
+ }
50
+ case 'instruction':
51
+ for (const operand of statement.operands) {
52
+ if (operand.kind === 'expr')
53
+ noteExpr(operand.expr);
54
+ else if (operand.kind === 'mem')
55
+ noteExpr(operand.offset);
56
+ }
57
+ break;
58
+ case 'directive': {
59
+ const d = statement.directive;
60
+ switch (d.kind) {
61
+ case 'section':
62
+ section = d.name;
63
+ break;
64
+ case 'globl':
65
+ globals.add(d.name);
66
+ note(d.name);
67
+ break;
68
+ case 'extern':
69
+ externs.set(d.name, d.size);
70
+ note(d.name);
71
+ break;
72
+ case 'common':
73
+ if (commons.has(d.name)) {
74
+ diagnostics.error(statement, 'duplicate-label', `${d.name} is already a common symbol.`);
75
+ }
76
+ else {
77
+ commons.set(d.name, { name: d.name, size: d.size, align: d.align, local: d.local });
78
+ }
79
+ note(d.name);
80
+ break;
81
+ case 'values':
82
+ d.values.forEach(noteExpr);
83
+ break;
84
+ default:
85
+ break;
86
+ }
87
+ break;
88
+ }
89
+ }
90
+ }
91
+ return { order, labels, globals, externs, commons };
92
+ }
93
+ /**
94
+ * The symbols ASPSX addresses through `$gp` at this -G value: labels in
95
+ * `.sdata`/`.sbss`, commons no larger than the threshold, and (only with
96
+ * `experimental.externSmallData`) externs declared no larger than it.
97
+ */
98
+ export function classifySmallData(table, gpSize, externSmallData) {
99
+ const small = new Map();
100
+ if (gpSize === 0)
101
+ return small;
102
+ for (const name of table.order) {
103
+ const label = table.labels.get(name);
104
+ const common = table.commons.get(name);
105
+ const externSize = table.externs.get(name);
106
+ if (label !== undefined) {
107
+ if (label.section === '.sdata' || label.section === '.sbss') {
108
+ small.set(name, { name, reason: label.section === '.sdata' ? 'sdata' : 'sbss' });
109
+ }
110
+ }
111
+ else if (common !== undefined) {
112
+ if (common.size <= gpSize)
113
+ small.set(name, { name, reason: 'common', size: common.size });
114
+ }
115
+ else if (externSmallData && externSize !== undefined && externSize <= gpSize) {
116
+ // Off by default: ASPSX 2.81, like maspsx, ignores .extern sizes.
117
+ small.set(name, { name, reason: 'extern', size: externSize });
118
+ }
119
+ }
120
+ return small;
121
+ }
122
+ //# sourceMappingURL=symbols.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../../src/asm/symbols.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { ErrorCode } from './public-types.js';
2
+ /**
3
+ * Base class of every error thrown by psyq-asm. Problems in the assembly input
4
+ * are diagnostics in a failed result, not errors; errors are reserved for
5
+ * caller mistakes.
6
+ *
7
+ * Each subclass redeclares `code` as its own literal, so `code` is a
8
+ * discriminant. The redeclarations are `declare`-only; the base constructor is
9
+ * what assigns the value. A generic base would read better but would make
10
+ * `code` `any` after `x instanceof PsyqAsmError`, since instanceof narrowing
11
+ * fills a generic class's type arguments with `any`.
12
+ */
13
+ export declare class PsyqAsmError extends Error {
14
+ readonly code: ErrorCode;
15
+ constructor(code: ErrorCode, message: string, options?: ErrorOptions);
16
+ }
17
+ /** Options given to `assemble`, `decodeWords`, or `format` are malformed. */
18
+ export declare class InvalidOptionsError extends PsyqAsmError {
19
+ readonly code: 'invalid-options';
20
+ constructor(message: string);
21
+ }
22
+ /** `encode` was given an instruction whose operands cannot be encoded. */
23
+ export declare class InvalidInstructionError extends PsyqAsmError {
24
+ readonly code: 'invalid-instruction';
25
+ constructor(message: string);
26
+ }
27
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;gBAEb,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAKrE;AAED,6EAA6E;AAC7E,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,SAAiB,IAAI,EAAE,iBAAiB,CAAC;gBAE7B,OAAO,EAAE,MAAM;CAI5B;AAED,0EAA0E;AAC1E,qBAAa,uBAAwB,SAAQ,YAAY;IACvD,SAAiB,IAAI,EAAE,qBAAqB,CAAC;gBAEjC,OAAO,EAAE,MAAM;CAI5B"}
package/dist/errors.js ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Base class of every error thrown by psyq-asm. Problems in the assembly input
3
+ * are diagnostics in a failed result, not errors; errors are reserved for
4
+ * caller mistakes.
5
+ *
6
+ * Each subclass redeclares `code` as its own literal, so `code` is a
7
+ * discriminant. The redeclarations are `declare`-only; the base constructor is
8
+ * what assigns the value. A generic base would read better but would make
9
+ * `code` `any` after `x instanceof PsyqAsmError`, since instanceof narrowing
10
+ * fills a generic class's type arguments with `any`.
11
+ */
12
+ export class PsyqAsmError extends Error {
13
+ code;
14
+ constructor(code, message, options) {
15
+ super(message, options);
16
+ this.code = code;
17
+ this.name = 'PsyqAsmError';
18
+ }
19
+ }
20
+ /** Options given to `assemble`, `decodeWords`, or `format` are malformed. */
21
+ export class InvalidOptionsError extends PsyqAsmError {
22
+ constructor(message) {
23
+ super('invalid-options', message);
24
+ this.name = 'InvalidOptionsError';
25
+ }
26
+ }
27
+ /** `encode` was given an instruction whose operands cannot be encoded. */
28
+ export class InvalidInstructionError extends PsyqAsmError {
29
+ constructor(message) {
30
+ super('invalid-instruction', message);
31
+ this.name = 'InvalidInstructionError';
32
+ }
33
+ }
34
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAY;IAEzB,YAAY,IAAe,EAAE,OAAe,EAAE,OAAsB;QAClE,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED,6EAA6E;AAC7E,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IAGnD,YAAY,OAAe;QACzB,KAAK,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AAED,0EAA0E;AAC1E,MAAM,OAAO,uBAAwB,SAAQ,YAAY;IAGvD,YAAY,OAAe;QACzB,KAAK,CAAC,qBAAqB,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;IACxC,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * psyq-asm: an ASPSX 2.81-compatible assembler and R3000 encoder/decoder.
3
+ */
4
+ export type { AspsxVersion, AssembledObject, AssembleFailure, AssembleOptions, AssembleResult, AssembleSuccess, DecodedProgram, DecodeOptions, Diagnostic, DiagnosticCode, EncodableInstruction, ErrorCode, ExperimentalBehaviours, FormatStyle, FunctionRange, HazardClass, Instruction, InstructionFormat, Mnemonic, Operand, Relocation, RelocationKind, RelocationTarget, Section, SectionName, SmallDataEntry, SymbolEntry, UnknownInstruction, WordOrigin, WordOriginKind, } from './public-types.js';
5
+ export { InvalidInstructionError, InvalidOptionsError, PsyqAsmError } from './errors.js';
6
+ export { DEFAULT_EXPERIMENTAL, SUPPORTED_ASPSX_VERSIONS } from './options.js';
7
+ export { assemble } from './asm/assemble.js';
8
+ export { decode } from './isa/decode.js';
9
+ export { encode } from './isa/encode.js';
10
+ export { format } from './isa/format.js';
11
+ export { REGISTER_NAMES, parseRegister } from './isa/registers.js';
12
+ export { decodeWords } from './program/decode-words.js';
13
+ export { formatProgram } from './program/format-program.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,YAAY,EACV,YAAY,EACZ,eAAe,EACf,eAAe,EACf,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,EACb,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,SAAS,EACT,sBAAsB,EACtB,WAAW,EACX,aAAa,EACb,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,QAAQ,EACR,OAAO,EACP,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,OAAO,EACP,WAAW,EACX,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,UAAU,EACV,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ export { InvalidInstructionError, InvalidOptionsError, PsyqAsmError } from './errors.js';
2
+ export { DEFAULT_EXPERIMENTAL, SUPPORTED_ASPSX_VERSIONS } from './options.js';
3
+ export { assemble } from './asm/assemble.js';
4
+ export { decode } from './isa/decode.js';
5
+ export { encode } from './isa/encode.js';
6
+ export { format } from './isa/format.js';
7
+ export { REGISTER_NAMES, parseRegister } from './isa/registers.js';
8
+ export { decodeWords } from './program/decode-words.js';
9
+ export { formatProgram } from './program/format-program.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoCA,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { Instruction, UnknownInstruction } from '../public-types.js';
2
+ /**
3
+ * Decode one R3000 word. Reserved and unknown encodings return an
4
+ * `UnknownInstruction` rather than throwing. Throws `InvalidInstructionError`
5
+ * only when `word` is not a 32-bit integer (signed or unsigned).
6
+ */
7
+ export declare function decode(word: number): Instruction | UnknownInstruction;
8
+ //# sourceMappingURL=decode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/isa/decode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAW,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAiFnF;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,kBAAkB,CAiBrE"}
@@ -0,0 +1,92 @@
1
+ // SPDX-License-Identifier: MIT
2
+ import { InvalidInstructionError } from '../errors.js';
3
+ import { COP_SLOTS, signExtend16 } from './fields.js';
4
+ import { buildInstruction, reservedBits } from './instruction.js';
5
+ import { ISA_ROWS } from './table.js';
6
+ /** Rows grouped by primary opcode, each with its reserved bits precomputed. */
7
+ const BY_OPCODE = (() => {
8
+ const map = new Map();
9
+ for (const row of ISA_ROWS) {
10
+ const op = row.value >>> 26;
11
+ const bucket = map.get(op) ?? [];
12
+ bucket.push({ row, reserved: reservedBits(row) });
13
+ map.set(op, bucket);
14
+ }
15
+ return map;
16
+ })();
17
+ function hex(value, digits) {
18
+ return `0x${value.toString(16).toUpperCase().padStart(digits, '0')}`;
19
+ }
20
+ function operandFor(slot, word) {
21
+ switch (slot) {
22
+ case 'rd':
23
+ return { kind: 'gpr', number: (word >>> 11) & 31 };
24
+ case 'rs':
25
+ return { kind: 'gpr', number: (word >>> 21) & 31 };
26
+ case 'rt':
27
+ return { kind: 'gpr', number: (word >>> 16) & 31 };
28
+ case 'sa':
29
+ return { kind: 'shamt', value: (word >>> 6) & 31 };
30
+ case 'imm16s':
31
+ return { kind: 'imm', value: signExtend16(word), bits: 16, signed: true };
32
+ case 'imm16u':
33
+ return { kind: 'imm', value: word & 0xffff, bits: 16, signed: false };
34
+ case 'mem':
35
+ return { kind: 'mem', base: (word >>> 21) & 31, offset: signExtend16(word) };
36
+ case 'branch':
37
+ return { kind: 'branch', displacement: signExtend16(word) };
38
+ case 'target':
39
+ return { kind: 'target', index: word & 0x03ffffff };
40
+ case 'code20':
41
+ return { kind: 'imm', value: (word >>> 6) & 0xfffff, bits: 20, signed: false };
42
+ case 'code10hi':
43
+ return { kind: 'imm', value: (word >>> 16) & 0x3ff, bits: 10, signed: false };
44
+ case 'code10':
45
+ return { kind: 'imm', value: (word >>> 6) & 0x3ff, bits: 10, signed: false };
46
+ case 'imm25':
47
+ return { kind: 'imm', value: word & 0x01ffffff, bits: 25, signed: false };
48
+ case 'cop0':
49
+ case 'cop2d':
50
+ case 'cop2c':
51
+ case 'cop2dRt': {
52
+ const { unit, space, shift } = COP_SLOTS[slot];
53
+ return { kind: 'cop', number: (word >>> shift) & 31, unit, space };
54
+ }
55
+ }
56
+ }
57
+ function unknownReason(word) {
58
+ const op = word >>> 26;
59
+ switch (op) {
60
+ case 0x00:
61
+ return `unknown SPECIAL function ${hex(word & 0x3f, 2)}`;
62
+ case 0x01:
63
+ return `unknown REGIMM condition ${hex((word >>> 16) & 31, 2)}`;
64
+ case 0x10:
65
+ return 'unknown coprocessor 0 operation';
66
+ case 0x12:
67
+ return 'unknown coprocessor 2 operation';
68
+ default:
69
+ return `unknown opcode ${hex(op, 2)}`;
70
+ }
71
+ }
72
+ /**
73
+ * Decode one R3000 word. Reserved and unknown encodings return an
74
+ * `UnknownInstruction` rather than throwing. Throws `InvalidInstructionError`
75
+ * only when `word` is not a 32-bit integer (signed or unsigned).
76
+ */
77
+ export function decode(word) {
78
+ if (!Number.isInteger(word) || word < -0x80000000 || word > 0xffffffff) {
79
+ throw new InvalidInstructionError(`word must be a 32-bit integer, not ${String(word)}.`);
80
+ }
81
+ const w = word >>> 0;
82
+ for (const { row: r, reserved } of BY_OPCODE.get(w >>> 26) ?? []) {
83
+ if ((w & r.mask) >>> 0 !== r.value)
84
+ continue;
85
+ if ((w & reserved) >>> 0 !== 0) {
86
+ return { mnemonic: '.word', word: w, reason: `${r.mnemonic} with reserved bits set` };
87
+ }
88
+ return buildInstruction(r, r.syntax.map((slot) => operandFor(slot, w)), w);
89
+ }
90
+ return { mnemonic: '.word', word: w, reason: unknownReason(w) };
91
+ }
92
+ //# sourceMappingURL=decode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode.js","sourceRoot":"","sources":["../../src/isa/decode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { EncodableInstruction } from '../public-types.js';
2
+ /**
3
+ * Encode one instruction. The operands are in assembly order, as `decode`
4
+ * produces them; `jalr rs` may omit the link register and `syscall`, `break`,
5
+ * and `tge` may omit their code. Throws `InvalidInstructionError` for an
6
+ * unknown mnemonic or an operand that does not fit.
7
+ */
8
+ export declare function encode(instruction: EncodableInstruction): number;
9
+ //# sourceMappingURL=encode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../src/isa/encode.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAW,MAAM,oBAAoB,CAAC;AAwGxE;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,WAAW,EAAE,oBAAoB,GAAG,MAAM,CAmChE"}