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.
- package/CHANGELOG.md +65 -0
- package/LICENSE +56 -0
- package/README.md +220 -0
- package/bin/psyq-asm.mjs +149 -0
- package/dist/asm/assemble.d.ts +10 -0
- package/dist/asm/assemble.d.ts.map +1 -0
- package/dist/asm/assemble.js +42 -0
- package/dist/asm/assemble.js.map +1 -0
- package/dist/asm/diagnostics.d.ts +22 -0
- package/dist/asm/diagnostics.d.ts.map +1 -0
- package/dist/asm/diagnostics.js +40 -0
- package/dist/asm/diagnostics.js.map +1 -0
- package/dist/asm/directives.d.ts +67 -0
- package/dist/asm/directives.d.ts.map +1 -0
- package/dist/asm/directives.js +254 -0
- package/dist/asm/directives.js.map +1 -0
- package/dist/asm/expand.d.ts +21 -0
- package/dist/asm/expand.d.ts.map +1 -0
- package/dist/asm/expand.js +540 -0
- package/dist/asm/expand.js.map +1 -0
- package/dist/asm/hazards.d.ts +10 -0
- package/dist/asm/hazards.d.ts.map +1 -0
- package/dist/asm/hazards.js +196 -0
- package/dist/asm/hazards.js.map +1 -0
- package/dist/asm/layout.d.ts +17 -0
- package/dist/asm/layout.d.ts.map +1 -0
- package/dist/asm/layout.js +257 -0
- package/dist/asm/layout.js.map +1 -0
- package/dist/asm/lexer.d.ts +23 -0
- package/dist/asm/lexer.d.ts.map +1 -0
- package/dist/asm/lexer.js +81 -0
- package/dist/asm/lexer.js.map +1 -0
- package/dist/asm/object.d.ts +6 -0
- package/dist/asm/object.d.ts.map +1 -0
- package/dist/asm/object.js +46 -0
- package/dist/asm/object.js.map +1 -0
- package/dist/asm/operands.d.ts +49 -0
- package/dist/asm/operands.d.ts.map +1 -0
- package/dist/asm/operands.js +114 -0
- package/dist/asm/operands.js.map +1 -0
- package/dist/asm/parser.d.ts +28 -0
- package/dist/asm/parser.d.ts.map +1 -0
- package/dist/asm/parser.js +60 -0
- package/dist/asm/parser.js.map +1 -0
- package/dist/asm/relocations.d.ts +42 -0
- package/dist/asm/relocations.d.ts.map +1 -0
- package/dist/asm/relocations.js +214 -0
- package/dist/asm/relocations.js.map +1 -0
- package/dist/asm/sections.d.ts +23 -0
- package/dist/asm/sections.d.ts.map +1 -0
- package/dist/asm/sections.js +81 -0
- package/dist/asm/sections.js.map +1 -0
- package/dist/asm/stream.d.ts +77 -0
- package/dist/asm/stream.d.ts.map +1 -0
- package/dist/asm/stream.js +2 -0
- package/dist/asm/stream.js.map +1 -0
- package/dist/asm/symbols.d.ts +42 -0
- package/dist/asm/symbols.d.ts.map +1 -0
- package/dist/asm/symbols.js +122 -0
- package/dist/asm/symbols.js.map +1 -0
- package/dist/errors.d.ts +27 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +34 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/isa/decode.d.ts +8 -0
- package/dist/isa/decode.d.ts.map +1 -0
- package/dist/isa/decode.js +92 -0
- package/dist/isa/decode.js.map +1 -0
- package/dist/isa/encode.d.ts +9 -0
- package/dist/isa/encode.d.ts.map +1 -0
- package/dist/isa/encode.js +124 -0
- package/dist/isa/encode.js.map +1 -0
- package/dist/isa/fields.d.ts +27 -0
- package/dist/isa/fields.d.ts.map +1 -0
- package/dist/isa/fields.js +49 -0
- package/dist/isa/fields.js.map +1 -0
- package/dist/isa/format.d.ts +14 -0
- package/dist/isa/format.d.ts.map +1 -0
- package/dist/isa/format.js +98 -0
- package/dist/isa/format.js.map +1 -0
- package/dist/isa/instruction.d.ts +15 -0
- package/dist/isa/instruction.d.ts.map +1 -0
- package/dist/isa/instruction.js +47 -0
- package/dist/isa/instruction.js.map +1 -0
- package/dist/isa/registers.d.ts +8 -0
- package/dist/isa/registers.d.ts.map +1 -0
- package/dist/isa/registers.js +55 -0
- package/dist/isa/registers.js.map +1 -0
- package/dist/isa/table.d.ts +179 -0
- package/dist/isa/table.d.ts.map +1 -0
- package/dist/isa/table.js +128 -0
- package/dist/isa/table.js.map +1 -0
- package/dist/options.d.ts +29 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +0 -0
- package/dist/options.js.map +1 -0
- package/dist/program/decode-words.d.ts +9 -0
- package/dist/program/decode-words.d.ts.map +1 -0
- package/dist/program/decode-words.js +87 -0
- package/dist/program/decode-words.js.map +1 -0
- package/dist/program/format-program.d.ts +12 -0
- package/dist/program/format-program.d.ts.map +1 -0
- package/dist/program/format-program.js +37 -0
- package/dist/program/format-program.js.map +1 -0
- package/dist/public-types.d.ts +253 -0
- package/dist/public-types.d.ts.map +1 -0
- package/dist/public-types.js +2 -0
- package/dist/public-types.js.map +1 -0
- package/dist/util.d.ts +3 -0
- package/dist/util.d.ts.map +1 -0
- package/dist/util.js +11 -0
- package/dist/util.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
/**
|
|
3
|
+
* The nop pass: where ASPSX 2.81 inserts nops (docs/ASPSX-2.81.md, "Hazard
|
|
4
|
+
* nops"). Rules, after maspsx:
|
|
5
|
+
*
|
|
6
|
+
* - H1: after every branch and jump under `.set reorder`.
|
|
7
|
+
* - H2: after a load, when the next instruction's first word reads the loaded
|
|
8
|
+
* register. A `div`/`rem` expansion's final mflo/mfhi counts as a load.
|
|
9
|
+
* - H3: between mflo/mfhi and the next mult/div there must be two instructions.
|
|
10
|
+
* - H4: after mfc2/cfc2, like H2, when enabled.
|
|
11
|
+
*
|
|
12
|
+
* The pass works on the expanded stream, so "the next instruction" is always
|
|
13
|
+
* the first word of the next group: a macro that starts with `lui $at` does not
|
|
14
|
+
* read the loaded register, while a one-word `$gp`-relative rewrite may.
|
|
15
|
+
* Nops are anchored exactly where maspsx places them, because anchoring decides
|
|
16
|
+
* which address a label between the two instructions receives.
|
|
17
|
+
*/
|
|
18
|
+
import { hazardReadsOf, registersOf } from '../isa/instruction.js';
|
|
19
|
+
import { ISA_ROWS } from '../isa/table.js';
|
|
20
|
+
/** The first row of the table is `sll`, whose all-zero word is the nop. */
|
|
21
|
+
const SLL = ISA_ROWS[0];
|
|
22
|
+
function nopWord(origin, note) {
|
|
23
|
+
return {
|
|
24
|
+
row: SLL,
|
|
25
|
+
args: [
|
|
26
|
+
{ slot: 'rd', value: { kind: 'gpr', number: 0 } },
|
|
27
|
+
{ slot: 'rt', value: { kind: 'gpr', number: 0 } },
|
|
28
|
+
{ slot: 'sa', value: { kind: 'value', expr: { kind: 'number', value: 0 } } },
|
|
29
|
+
],
|
|
30
|
+
origin,
|
|
31
|
+
note,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** A group's first and last words (a nop for the never-produced empty group). */
|
|
35
|
+
export function endsOf(group) {
|
|
36
|
+
const { words } = group;
|
|
37
|
+
const fallback = nopWord('instruction', 'empty group');
|
|
38
|
+
return [words[0] ?? fallback, words[words.length - 1] ?? fallback];
|
|
39
|
+
}
|
|
40
|
+
/** A word with only its register fields filled in: enough to ask the table about register use. */
|
|
41
|
+
function registerWord(word) {
|
|
42
|
+
let bits = word.row.value;
|
|
43
|
+
for (const { slot, value } of word.args) {
|
|
44
|
+
if (value.kind === 'gpr')
|
|
45
|
+
bits |= value.number << (slot === 'rd' ? 11 : slot === 'rs' ? 21 : 16);
|
|
46
|
+
else if (value.kind === 'mem')
|
|
47
|
+
bits |= value.base << 21;
|
|
48
|
+
}
|
|
49
|
+
return bits >>> 0;
|
|
50
|
+
}
|
|
51
|
+
function readsOf(word) {
|
|
52
|
+
return hazardReadsOf(word.row, registerWord(word));
|
|
53
|
+
}
|
|
54
|
+
function writesOf(word) {
|
|
55
|
+
return registersOf(word.row.writes, registerWord(word));
|
|
56
|
+
}
|
|
57
|
+
function nop(near, origin, note) {
|
|
58
|
+
return {
|
|
59
|
+
kind: 'group',
|
|
60
|
+
line: near.line,
|
|
61
|
+
column: near.column,
|
|
62
|
+
section: near.section,
|
|
63
|
+
reorder: near.reorder,
|
|
64
|
+
words: [nopWord(origin, note)],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The next `count` groups after `from`, looking past `.set` options and
|
|
69
|
+
* transparent labels and stopping at any other item, as maspsx's lookahead
|
|
70
|
+
* does.
|
|
71
|
+
*/
|
|
72
|
+
function following(items, from, count) {
|
|
73
|
+
const found = [];
|
|
74
|
+
let noreorderAt;
|
|
75
|
+
for (const [offset, item] of items.slice(from + 1).entries()) {
|
|
76
|
+
if (found.length === count)
|
|
77
|
+
break;
|
|
78
|
+
const index = from + 1 + offset;
|
|
79
|
+
if (item.kind === 'set') {
|
|
80
|
+
if (item.option === 'noreorder' && noreorderAt === undefined)
|
|
81
|
+
noreorderAt = index;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
// VERIFY-21: every transparent label, `L`-prefixed debugging markers
|
|
85
|
+
// included, stays before a nop inserted ahead of the next group; maspsx
|
|
86
|
+
// leaves `L` markers after it. The difference is invisible at -g0.
|
|
87
|
+
if (item.kind === 'label' && item.transparent)
|
|
88
|
+
continue;
|
|
89
|
+
if (item.kind !== 'group')
|
|
90
|
+
break;
|
|
91
|
+
found.push({ group: item, index, noreorderAt });
|
|
92
|
+
noreorderAt = undefined;
|
|
93
|
+
}
|
|
94
|
+
return found;
|
|
95
|
+
}
|
|
96
|
+
function isMultiplyOrDivide(group) {
|
|
97
|
+
const hazard = endsOf(group)[0].row.hazard;
|
|
98
|
+
return hazard === 'mult' || hazard === 'div';
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* H3 after an mflo/mfhi (maspsx `_handle_mflo_mfhi`). Returns true when the
|
|
102
|
+
* rule took charge of what follows, which suppresses the load-delay check of a
|
|
103
|
+
* div expansion.
|
|
104
|
+
*/
|
|
105
|
+
function multiplyGap(items, index, producer, insert) {
|
|
106
|
+
const [first, second] = following(items, index, 2);
|
|
107
|
+
if (first === undefined)
|
|
108
|
+
return false;
|
|
109
|
+
const tail = endsOf(producer)[1].row.mnemonic;
|
|
110
|
+
const gap = () => nop(producer, 'hilo-gap-nop', `a mult or div may not start within two instructions of ${tail}`);
|
|
111
|
+
if (isMultiplyOrDivide(first.group)) {
|
|
112
|
+
insert(first.index, gap());
|
|
113
|
+
insert(first.index, gap());
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (second === undefined || !isMultiplyOrDivide(second.group))
|
|
117
|
+
return false;
|
|
118
|
+
const between = endsOf(first.group)[0];
|
|
119
|
+
// Another mflo/mfhi in between restarts the count.
|
|
120
|
+
if (between.row.hazard === 'mflo')
|
|
121
|
+
return false;
|
|
122
|
+
if (first.group.macro === 'li') {
|
|
123
|
+
if (first.group.words.length === 1)
|
|
124
|
+
insert(first.index + 1, gap());
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
if (first.noreorderAt !== undefined) {
|
|
128
|
+
insert(first.noreorderAt, gap());
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
if (producer.divMove !== undefined && readsOf(between).includes(producer.divMove)) {
|
|
132
|
+
insert(first.index, gap());
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
if (between.row.hazard === 'branch' || between.row.hazard === 'jump') {
|
|
136
|
+
// Under reorder, the branch's own delay-slot nop fills the gap.
|
|
137
|
+
if (!first.group.reorder)
|
|
138
|
+
insert(first.index + 1, gap());
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
// A multi-word expansion fills the gap, as a two-word li does.
|
|
142
|
+
if (first.group.words.length > 1)
|
|
143
|
+
return true;
|
|
144
|
+
insert(second.index, gap());
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
/** The register whose load makes the next instruction wait, if any. */
|
|
148
|
+
function delayedRegister(group, options) {
|
|
149
|
+
if (group.divMove !== undefined)
|
|
150
|
+
return { register: group.divMove, origin: 'load-delay-nop' };
|
|
151
|
+
const tail = endsOf(group)[1];
|
|
152
|
+
const [written] = writesOf(tail);
|
|
153
|
+
if (written === undefined)
|
|
154
|
+
return undefined;
|
|
155
|
+
if (tail.row.hazard === 'load')
|
|
156
|
+
return { register: written, origin: 'load-delay-nop' };
|
|
157
|
+
if (tail.row.hazard === 'cop-from' && options.copMoveDelayNop) {
|
|
158
|
+
return { register: written, origin: 'cop-delay-nop' };
|
|
159
|
+
}
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
/** Insert the nops ASPSX 2.81 would, returning a new stream. */
|
|
163
|
+
export function insertNops(items, options) {
|
|
164
|
+
const inserts = new Map();
|
|
165
|
+
const insert = (before, group) => {
|
|
166
|
+
inserts.set(before, [...(inserts.get(before) ?? []), group]);
|
|
167
|
+
};
|
|
168
|
+
items.forEach((item, index) => {
|
|
169
|
+
if (item.kind !== 'group')
|
|
170
|
+
return;
|
|
171
|
+
const tail = endsOf(item)[1];
|
|
172
|
+
const { hazard, mnemonic } = tail.row;
|
|
173
|
+
if ((hazard === 'branch' || hazard === 'jump') && item.reorder) {
|
|
174
|
+
insert(index + 1, nop(item, 'branch-delay-nop', `the delay slot of ${mnemonic} under .set reorder`));
|
|
175
|
+
}
|
|
176
|
+
if (hazard === 'mflo' && multiplyGap(items, index, item, insert))
|
|
177
|
+
return;
|
|
178
|
+
// A load under .set noreorder is left alone.
|
|
179
|
+
const delayed = item.reorder || tail.row.hazard !== 'load' ? delayedRegister(item, options) : undefined;
|
|
180
|
+
const [next] = following(items, index, 1);
|
|
181
|
+
if (delayed === undefined || next === undefined)
|
|
182
|
+
return;
|
|
183
|
+
// A multiply-gap nop already in front of the reader serves as the delay too.
|
|
184
|
+
if (inserts.has(next.index))
|
|
185
|
+
return;
|
|
186
|
+
const reader = endsOf(next.group)[0];
|
|
187
|
+
if (!readsOf(reader).includes(delayed.register))
|
|
188
|
+
return;
|
|
189
|
+
insert(next.index, nop(item, delayed.origin, `$${String(delayed.register)} is written by ${mnemonic} and read by ${reader.row.mnemonic}`));
|
|
190
|
+
});
|
|
191
|
+
return [
|
|
192
|
+
...items.flatMap((item, index) => [...(inserts.get(index) ?? []), item]),
|
|
193
|
+
...(inserts.get(items.length) ?? []),
|
|
194
|
+
];
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=hazards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hazards.js","sourceRoot":"","sources":["../../src/asm/hazards.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FunctionRange, Section } from '../public-types.js';
|
|
2
|
+
import type { Diagnostics } from './diagnostics.js';
|
|
3
|
+
import { type LabelLocation } from './relocations.js';
|
|
4
|
+
import type { Item } from './stream.js';
|
|
5
|
+
import type { SymbolTable } from './symbols.js';
|
|
6
|
+
export interface Layout {
|
|
7
|
+
readonly sections: readonly Section[];
|
|
8
|
+
readonly labels: ReadonlyMap<string, LabelLocation>;
|
|
9
|
+
readonly functions: readonly FunctionRange[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* VERIFY-5: alignment of a `.comm`/`.lcomm` allocation when none is given, from
|
|
13
|
+
* its size (maspsx aligns `.sbss` entries this way).
|
|
14
|
+
*/
|
|
15
|
+
export declare function commonAlignment(size: number, explicit: number | undefined): number;
|
|
16
|
+
export declare function layout(items: readonly Item[], symbols: SymbolTable, gpSize: number, diagnostics: Diagnostics): Layout;
|
|
17
|
+
//# sourceMappingURL=layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../src/asm/layout.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAqB,OAAO,EAAc,MAAM,oBAAoB,CAAC;AAChG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAS,IAAI,EAAe,MAAM,aAAa,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACpD,QAAQ,CAAC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;CAC9C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKlF;AAoQD,wBAAgB,MAAM,CACpB,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,WAAW,GACvB,MAAM,CAGR"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
/**
|
|
3
|
+
* Layout: pass A assigns every label its section offset (after expansion and
|
|
4
|
+
* nop insertion have fixed each group's size, and after `.comm` allocation);
|
|
5
|
+
* pass B resolves operands and encodes words into section buffers.
|
|
6
|
+
*/
|
|
7
|
+
import { encode } from '../isa/encode.js';
|
|
8
|
+
import { isError, resolveArg, resolveData, } from './relocations.js';
|
|
9
|
+
import { SectionBuilder } from './sections.js';
|
|
10
|
+
/**
|
|
11
|
+
* VERIFY-5: alignment of a `.comm`/`.lcomm` allocation when none is given, from
|
|
12
|
+
* its size (maspsx aligns `.sbss` entries this way).
|
|
13
|
+
*/
|
|
14
|
+
export function commonAlignment(size, explicit) {
|
|
15
|
+
if (explicit !== undefined)
|
|
16
|
+
return explicit;
|
|
17
|
+
if (size >= 8)
|
|
18
|
+
return 8;
|
|
19
|
+
if (size >= 4)
|
|
20
|
+
return 4;
|
|
21
|
+
return size >= 2 ? 2 : 1;
|
|
22
|
+
}
|
|
23
|
+
function padding(offset, alignment) {
|
|
24
|
+
return (alignment - (offset % alignment)) % alignment;
|
|
25
|
+
}
|
|
26
|
+
/** Commons no larger than the -G threshold go to `.sbss`, the rest to `.bss`. */
|
|
27
|
+
function commonSection(size, gpSize) {
|
|
28
|
+
return gpSize > 0 && size <= gpSize ? '.sbss' : '.bss';
|
|
29
|
+
}
|
|
30
|
+
function contentSize(directive) {
|
|
31
|
+
switch (directive.kind) {
|
|
32
|
+
case 'values':
|
|
33
|
+
return directive.unit * directive.values.length;
|
|
34
|
+
case 'bytes':
|
|
35
|
+
return directive.bytes.length;
|
|
36
|
+
case 'space':
|
|
37
|
+
return directive.size;
|
|
38
|
+
default:
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function assignLabels(items, symbols, gpSize) {
|
|
43
|
+
const sizes = new Map();
|
|
44
|
+
const labels = new Map();
|
|
45
|
+
const at = (section) => sizes.get(section) ?? 0;
|
|
46
|
+
const bind = (name, location) => {
|
|
47
|
+
if (!labels.has(name))
|
|
48
|
+
labels.set(name, location);
|
|
49
|
+
};
|
|
50
|
+
let section = '.text';
|
|
51
|
+
for (const item of items) {
|
|
52
|
+
if (item.kind === 'label') {
|
|
53
|
+
bind(item.name, { section, offset: at(section) });
|
|
54
|
+
}
|
|
55
|
+
else if (item.kind === 'group') {
|
|
56
|
+
sizes.set(item.section, at(item.section) + 4 * item.words.length);
|
|
57
|
+
}
|
|
58
|
+
else if (item.kind === 'directive') {
|
|
59
|
+
const d = item.directive;
|
|
60
|
+
if (d.kind === 'section')
|
|
61
|
+
section = d.name;
|
|
62
|
+
else if (d.kind === 'align')
|
|
63
|
+
sizes.set(section, at(section) + padding(at(section), 2 ** d.power));
|
|
64
|
+
else
|
|
65
|
+
sizes.set(section, at(section) + contentSize(d));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (const common of symbols.commons.values()) {
|
|
69
|
+
const target = commonSection(common.size, gpSize);
|
|
70
|
+
const offset = at(target) + padding(at(target), commonAlignment(common.size, common.align));
|
|
71
|
+
bind(common.name, { section: target, offset });
|
|
72
|
+
sizes.set(target, offset + common.size);
|
|
73
|
+
}
|
|
74
|
+
return labels;
|
|
75
|
+
}
|
|
76
|
+
function originOf(group, word) {
|
|
77
|
+
return {
|
|
78
|
+
line: group.line,
|
|
79
|
+
kind: word.origin,
|
|
80
|
+
...(group.macro === undefined || word.origin !== 'macro' ? {} : { macro: group.macro }),
|
|
81
|
+
...(word.note === undefined ? {} : { note: word.note }),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
class Emitter {
|
|
85
|
+
labels;
|
|
86
|
+
symbols;
|
|
87
|
+
gpSize;
|
|
88
|
+
diagnostics;
|
|
89
|
+
builders = new Map();
|
|
90
|
+
functions = [];
|
|
91
|
+
open;
|
|
92
|
+
section = '.text';
|
|
93
|
+
constructor(labels, symbols, gpSize, diagnostics) {
|
|
94
|
+
this.labels = labels;
|
|
95
|
+
this.symbols = symbols;
|
|
96
|
+
this.gpSize = gpSize;
|
|
97
|
+
this.diagnostics = diagnostics;
|
|
98
|
+
}
|
|
99
|
+
builder(name) {
|
|
100
|
+
let builder = this.builders.get(name);
|
|
101
|
+
if (builder === undefined) {
|
|
102
|
+
builder = new SectionBuilder(name);
|
|
103
|
+
this.builders.set(name, builder);
|
|
104
|
+
}
|
|
105
|
+
return builder;
|
|
106
|
+
}
|
|
107
|
+
run(items) {
|
|
108
|
+
for (const item of items) {
|
|
109
|
+
if (item.kind === 'label')
|
|
110
|
+
this.builder(this.section);
|
|
111
|
+
else if (item.kind === 'group')
|
|
112
|
+
this.group(item);
|
|
113
|
+
else if (item.kind === 'directive')
|
|
114
|
+
this.directive(item.directive, item);
|
|
115
|
+
}
|
|
116
|
+
if (this.open !== undefined) {
|
|
117
|
+
this.diagnostics.warning({ line: this.open.line }, 'function-mismatch', `.ent ${this.open.name} has no matching .end.`);
|
|
118
|
+
}
|
|
119
|
+
for (const common of this.symbols.commons.values()) {
|
|
120
|
+
const builder = this.builder(commonSection(common.size, this.gpSize));
|
|
121
|
+
const align = commonAlignment(common.size, common.align);
|
|
122
|
+
builder.pad(padding(builder.offset, align) + common.size, { line: 1, kind: 'data' });
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
sections: [...this.builders.values()].map((b) => b.finish()),
|
|
126
|
+
labels: this.labels,
|
|
127
|
+
functions: this.functions,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
group(group) {
|
|
131
|
+
const builder = this.builder(group.section);
|
|
132
|
+
for (const word of group.words) {
|
|
133
|
+
const offset = builder.offset;
|
|
134
|
+
const ctx = { labels: this.labels, section: group.section, offset };
|
|
135
|
+
const operands = [];
|
|
136
|
+
const relocations = [];
|
|
137
|
+
let failed = false;
|
|
138
|
+
for (const { slot, value } of word.args) {
|
|
139
|
+
const resolved = resolveArg(slot, value, ctx);
|
|
140
|
+
if (isError(resolved)) {
|
|
141
|
+
this.diagnostics.error(group, resolved.code, `${word.row.mnemonic}: ${resolved.message}`);
|
|
142
|
+
failed = true;
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
operands.push(resolved.value);
|
|
146
|
+
if (resolved.relocation !== undefined)
|
|
147
|
+
relocations.push(resolved.relocation);
|
|
148
|
+
}
|
|
149
|
+
const encoded = failed ? 0 : encode({ mnemonic: word.row.mnemonic, operands });
|
|
150
|
+
for (const relocation of relocations)
|
|
151
|
+
builder.relocations.push({ offset, ...relocation });
|
|
152
|
+
builder.pushWord(encoded, originOf(group, word));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
directive(d, at) {
|
|
156
|
+
const origin = { line: at.line, kind: 'data' };
|
|
157
|
+
switch (d.kind) {
|
|
158
|
+
case 'section':
|
|
159
|
+
this.section = d.name;
|
|
160
|
+
this.builder(d.name);
|
|
161
|
+
break;
|
|
162
|
+
case 'align': {
|
|
163
|
+
const builder = this.builder(this.section);
|
|
164
|
+
builder.pad(padding(builder.offset, 2 ** d.power), { line: at.line, kind: 'align' });
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
case 'space':
|
|
168
|
+
this.builder(this.section).pad(d.size, origin);
|
|
169
|
+
break;
|
|
170
|
+
case 'bytes':
|
|
171
|
+
case 'values':
|
|
172
|
+
this.data(d, at, origin);
|
|
173
|
+
break;
|
|
174
|
+
case 'ent':
|
|
175
|
+
if (this.open !== undefined) {
|
|
176
|
+
this.diagnostics.warning(at, 'function-mismatch', `.ent ${d.name} appears before .end ${this.open.name}.`);
|
|
177
|
+
}
|
|
178
|
+
this.open = {
|
|
179
|
+
name: d.name,
|
|
180
|
+
line: at.line,
|
|
181
|
+
start: Math.floor(this.builder('.text').offset / 4),
|
|
182
|
+
};
|
|
183
|
+
break;
|
|
184
|
+
case 'end':
|
|
185
|
+
this.end(d, at);
|
|
186
|
+
break;
|
|
187
|
+
case 'frame':
|
|
188
|
+
case 'mask':
|
|
189
|
+
case 'fmask':
|
|
190
|
+
if (this.open === undefined) {
|
|
191
|
+
this.diagnostics.warning(at, 'function-mismatch', `.${d.kind} appears outside a function.`);
|
|
192
|
+
}
|
|
193
|
+
else if (d.kind === 'frame') {
|
|
194
|
+
this.open.frame = { reg: d.reg, size: d.size, returnReg: d.returnReg };
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
this.open[d.kind] = { bits: d.bits, offset: d.offset };
|
|
198
|
+
}
|
|
199
|
+
break;
|
|
200
|
+
default:
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
data(d, at, origin) {
|
|
205
|
+
const builder = this.builder(this.section);
|
|
206
|
+
if (builder.kind === 'bss') {
|
|
207
|
+
this.diagnostics.error(at, 'invalid-directive', `${this.section} can only reserve space, not hold data.`);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (d.kind === 'bytes') {
|
|
211
|
+
builder.pushBytes(d.bytes, origin);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
for (const expr of d.values) {
|
|
215
|
+
const offset = builder.offset;
|
|
216
|
+
const resolved = resolveData(d.unit, expr, {
|
|
217
|
+
labels: this.labels,
|
|
218
|
+
section: this.section,
|
|
219
|
+
offset,
|
|
220
|
+
});
|
|
221
|
+
const bytes = new Uint8Array(d.unit);
|
|
222
|
+
if (isError(resolved)) {
|
|
223
|
+
this.diagnostics.error(at, resolved.code, resolved.message);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
for (let i = 0; i < d.unit; i++)
|
|
227
|
+
bytes[i] = (resolved.value >>> (8 * i)) & 0xff;
|
|
228
|
+
if (resolved.relocation !== undefined)
|
|
229
|
+
builder.relocations.push({ offset, ...resolved.relocation });
|
|
230
|
+
}
|
|
231
|
+
builder.pushBytes(bytes, origin);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
end(d, at) {
|
|
235
|
+
const open = this.open;
|
|
236
|
+
this.open = undefined;
|
|
237
|
+
if (open === undefined || (d.name !== undefined && d.name !== open.name)) {
|
|
238
|
+
const name = d.name === undefined ? '.end' : `.end ${d.name}`;
|
|
239
|
+
this.diagnostics.warning(at, 'function-mismatch', `${name} does not close an open .ent.`);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
this.functions.push({
|
|
243
|
+
name: open.name,
|
|
244
|
+
section: '.text',
|
|
245
|
+
start: open.start,
|
|
246
|
+
end: Math.floor(this.builder('.text').offset / 4),
|
|
247
|
+
...(open.frame === undefined ? {} : { frame: open.frame }),
|
|
248
|
+
...(open.mask === undefined ? {} : { mask: open.mask }),
|
|
249
|
+
...(open.fmask === undefined ? {} : { fmask: open.fmask }),
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
export function layout(items, symbols, gpSize, diagnostics) {
|
|
254
|
+
const labels = assignLabels(items, symbols, gpSize);
|
|
255
|
+
return new Emitter(labels, symbols, gpSize, diagnostics).run(items);
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/asm/layout.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lines to statement text: comments stripped, `;`-separated statements split,
|
|
3
|
+
* `#APP`/`#NO_APP` inline-assembly regions flagged. Works on CRLF or LF input
|
|
4
|
+
* and keeps the original line and column of every piece.
|
|
5
|
+
*/
|
|
6
|
+
/** One statement's text with its source position. */
|
|
7
|
+
export interface SourcePiece {
|
|
8
|
+
readonly line: number;
|
|
9
|
+
readonly column: number;
|
|
10
|
+
readonly text: string;
|
|
11
|
+
/** Between `#APP` and `#NO_APP`: inline assembly from a C macro. */
|
|
12
|
+
readonly inlineAsm: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface Part {
|
|
15
|
+
readonly text: string;
|
|
16
|
+
readonly start: number;
|
|
17
|
+
}
|
|
18
|
+
/** Split `text` at `separator` wherever it is outside double quotes and parentheses. */
|
|
19
|
+
export declare function splitTopLevel(text: string, separator: string): Part[];
|
|
20
|
+
/** Remove a `#` comment, leaving `#` inside string literals alone. */
|
|
21
|
+
export declare function stripComment(text: string): string;
|
|
22
|
+
export declare function lex(source: string): SourcePiece[];
|
|
23
|
+
//# sourceMappingURL=lexer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../src/asm/lexer.ts"],"names":[],"mappings":"AACA;;;;GAIG;AAEH,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,CAuBrE;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcjD;AAED,wBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CAqBjD"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
/**
|
|
3
|
+
* Lines to statement text: comments stripped, `;`-separated statements split,
|
|
4
|
+
* `#APP`/`#NO_APP` inline-assembly regions flagged. Works on CRLF or LF input
|
|
5
|
+
* and keeps the original line and column of every piece.
|
|
6
|
+
*/
|
|
7
|
+
/** Split `text` at `separator` wherever it is outside double quotes and parentheses. */
|
|
8
|
+
export function splitTopLevel(text, separator) {
|
|
9
|
+
const parts = [];
|
|
10
|
+
let depth = 0;
|
|
11
|
+
let inString = false;
|
|
12
|
+
let start = 0;
|
|
13
|
+
for (let i = 0; i < text.length; i++) {
|
|
14
|
+
const c = text[i];
|
|
15
|
+
if (inString) {
|
|
16
|
+
if (c === '\\')
|
|
17
|
+
i++;
|
|
18
|
+
else if (c === '"')
|
|
19
|
+
inString = false;
|
|
20
|
+
}
|
|
21
|
+
else if (c === '"') {
|
|
22
|
+
inString = true;
|
|
23
|
+
}
|
|
24
|
+
else if (c === '(') {
|
|
25
|
+
depth++;
|
|
26
|
+
}
|
|
27
|
+
else if (c === ')') {
|
|
28
|
+
depth = Math.max(0, depth - 1);
|
|
29
|
+
}
|
|
30
|
+
else if (c === separator && depth === 0) {
|
|
31
|
+
parts.push({ text: text.slice(start, i), start });
|
|
32
|
+
start = i + 1;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
parts.push({ text: text.slice(start), start });
|
|
36
|
+
return parts;
|
|
37
|
+
}
|
|
38
|
+
/** Remove a `#` comment, leaving `#` inside string literals alone. */
|
|
39
|
+
export function stripComment(text) {
|
|
40
|
+
let inString = false;
|
|
41
|
+
for (let i = 0; i < text.length; i++) {
|
|
42
|
+
const c = text[i];
|
|
43
|
+
if (inString) {
|
|
44
|
+
if (c === '\\')
|
|
45
|
+
i++;
|
|
46
|
+
else if (c === '"')
|
|
47
|
+
inString = false;
|
|
48
|
+
}
|
|
49
|
+
else if (c === '"') {
|
|
50
|
+
inString = true;
|
|
51
|
+
}
|
|
52
|
+
else if (c === '#') {
|
|
53
|
+
return text.slice(0, i);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return text;
|
|
57
|
+
}
|
|
58
|
+
export function lex(source) {
|
|
59
|
+
const pieces = [];
|
|
60
|
+
let inlineAsm = false;
|
|
61
|
+
source.split(/\r?\n/).forEach((raw, index) => {
|
|
62
|
+
const marker = raw.trim();
|
|
63
|
+
if (marker === '#APP') {
|
|
64
|
+
inlineAsm = true;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (marker === '#NO_APP') {
|
|
68
|
+
inlineAsm = false;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
for (const part of splitTopLevel(stripComment(raw), ';')) {
|
|
72
|
+
const text = part.text.trim();
|
|
73
|
+
if (text === '')
|
|
74
|
+
continue;
|
|
75
|
+
const leading = part.text.length - part.text.trimStart().length;
|
|
76
|
+
pieces.push({ line: index + 1, column: part.start + leading + 1, text, inlineAsm });
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return pieces;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=lexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexer.js","sourceRoot":"","sources":["../../src/asm/lexer.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B;;;;GAIG;AAgBH,wFAAwF;AACxF,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,SAAiB;IAC3D,MAAM,KAAK,GAAW,EAAE,CAAC;IACzB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;iBACf,IAAI,CAAC,KAAK,GAAG;gBAAE,QAAQ,GAAG,KAAK,CAAC;QACvC,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,KAAK,EAAE,CAAC;QACV,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QACjC,CAAC;aAAM,IAAI,CAAC,KAAK,SAAS,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAClD,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/C,OAAO,KAAK,CAAC;AACf,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;iBACf,IAAI,CAAC,KAAK,GAAG;gBAAE,QAAQ,GAAG,KAAK,CAAC;QACvC,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,MAAc;IAChC,MAAM,MAAM,GAAkB,EAAE,CAAC;IACjC,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QAC3C,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,SAAS,GAAG,IAAI,CAAC;YACjB,OAAO;QACT,CAAC;QACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,SAAS,GAAG,KAAK,CAAC;YAClB,OAAO;QACT,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9B,IAAI,IAAI,KAAK,EAAE;gBAAE,SAAS;YAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC;YAChE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,GAAG,OAAO,GAAG,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QACtF,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { NormalizedAssembleOptions } from '../options.js';
|
|
2
|
+
import type { AssembledObject, SmallDataEntry } from '../public-types.js';
|
|
3
|
+
import type { Layout } from './layout.js';
|
|
4
|
+
import { type SymbolTable } from './symbols.js';
|
|
5
|
+
export declare function buildObject(options: NormalizedAssembleOptions, laidOut: Layout, table: SymbolTable, smallData: ReadonlyMap<string, SmallDataEntry>): AssembledObject;
|
|
6
|
+
//# sourceMappingURL=object.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../../src/asm/object.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAe,MAAM,oBAAoB,CAAC;AACvF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AA+B9D,wBAAgB,WAAW,CACzB,OAAO,EAAE,yBAAyB,EAClC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,GAC7C,eAAe,CAYjB"}
|