aboutsummaryrefslogtreecommitdiffgithub
diff options
context:
space:
mode:
authorAustin Adams <git@austinjadams.com>2019-01-18 15:34:29 -0500
committerAustin Adams <git@austinjadams.com>2019-01-18 15:34:29 -0500
commit20d5321a99ca84eb968531aeb2ed83e5e56a3435 (patch)
tree4d9074088d3f22737640e846c5287a9235909626
parent7772579a32a0f5176f650825b0a0a25002053d99 (diff)
downloadnovice-20d5321a99ca84eb968531aeb2ed83e5e56a3435.tar.gz
novice-20d5321a99ca84eb968531aeb2ed83e5e56a3435.tar.xz
Continue work on LC-2200 support
-rw-r--r--novice/assembler/configs.ts2
-rw-r--r--novice/assembler/opspec/index.ts5
-rw-r--r--novice/assembler/opspec/word.ts20
-rw-r--r--novice/assembler/parsers/grammars/lc2200.ts1
-rw-r--r--novice/assembler/parsers/lc2200.ts127
-rw-r--r--novice/assembler/parsers/tables/lc2200.ts2
-rw-r--r--novice/isa/index.ts5
-rw-r--r--novice/isa/isa.ts13
-rw-r--r--novice/isa/lc2200.ts6
9 files changed, 171 insertions, 10 deletions
diff --git a/novice/assembler/configs.ts b/novice/assembler/configs.ts
index 4cc6774..38005bb 100644
--- a/novice/assembler/configs.ts
+++ b/novice/assembler/configs.ts
@@ -15,7 +15,7 @@ const configs: {[s: string]: Config} = {
lc2200: {
parser: 'lc2200',
isa: 'lc2200',
- opSpec: 'complx',
+ opSpec: 'word',
serializer: 'complx',
},
};
diff --git a/novice/assembler/opspec/index.ts b/novice/assembler/opspec/index.ts
index 0f4315d..e8b03aa 100644
--- a/novice/assembler/opspec/index.ts
+++ b/novice/assembler/opspec/index.ts
@@ -1,8 +1,11 @@
import { complxOpSpec } from './complx';
import { AsmContext, OpOperands, OpSpec, PseudoOpSpec } from './opspec';
+import { wordOpSpec } from './word';
const opSpecs: {[s: string]: PseudoOpSpec} = {
complx: complxOpSpec,
+ word: wordOpSpec,
};
-export { AsmContext, OpOperands, OpSpec, PseudoOpSpec, complxOpSpec, opSpecs };
+export { AsmContext, OpOperands, OpSpec, PseudoOpSpec, complxOpSpec,
+ wordOpSpec, opSpecs };
diff --git a/novice/assembler/opspec/word.ts b/novice/assembler/opspec/word.ts
new file mode 100644
index 0000000..ed05de8
--- /dev/null
+++ b/novice/assembler/opspec/word.ts
@@ -0,0 +1,20 @@
+import { AsmContext, oneWord, OpOperands, PseudoOpSpec } from './opspec';
+
+const wordOpSpec: PseudoOpSpec = {
+ ops: [
+ {name: 'word',
+ operands: [{kind: 'int', name: 'num'}],
+ asm: (ctx: AsmContext, operands: OpOperands) =>
+ // TODO: complain if too big
+ [operands.ints.num & ~(-1 << ctx.isa.mem.addressability)]},
+
+ {name: 'word',
+ operands: [{kind: 'label', name: 'label'}],
+ size: oneWord,
+ asm: (ctx: AsmContext, operands: OpOperands) =>
+ // TODO: complain if nonexistent
+ [ctx.symbtable[operands.labels.label]]},
+ ],
+};
+
+export { wordOpSpec };
diff --git a/novice/assembler/parsers/grammars/lc2200.ts b/novice/assembler/parsers/grammars/lc2200.ts
index d22d74c..5e6b955 100644
--- a/novice/assembler/parsers/grammars/lc2200.ts
+++ b/novice/assembler/parsers/grammars/lc2200.ts
@@ -37,6 +37,7 @@ const productions: Production<NT, T>[] = [
{lhs: 'line', rhs: ['pseudoop-line']},
{lhs: 'label', rhs: []},
{lhs: 'label', rhs: ['label', 'word', ':']},
+ {lhs: 'instr', rhs: ['label', 'word']},
{lhs: 'instr', rhs: ['label', 'word', 'instr-operands']},
{lhs: 'instr-operands', rhs: ['operand']},
{lhs: 'instr-operands', rhs: ['instr-operands', ',', 'operand']},
diff --git a/novice/assembler/parsers/lc2200.ts b/novice/assembler/parsers/lc2200.ts
index 3e52f20..b416bda 100644
--- a/novice/assembler/parsers/lc2200.ts
+++ b/novice/assembler/parsers/lc2200.ts
@@ -1,5 +1,5 @@
// Parser for LC-2200 syntax
-import { Isa } from '../../isa';
+import { getAliases, Isa } from '../../isa';
import { ParseTable, ParseTree } from '../lr1';
import { Grammar } from './grammar';
import { grammar, NT, T } from './grammars/lc2200';
@@ -9,6 +9,9 @@ import { AbstractParser, Instruction, IntegerOperand, LabelOperand, Line,
import table from './tables/lc2200';
interface ParseContext {
+ instrs: (Instruction|PseudoOp)[];
+ labels: {[s: string]: number};
+ labelQueue: string[];
}
class Lc2200Parser extends AbstractParser<ParseContext, NT, T> {
@@ -21,16 +24,134 @@ class Lc2200Parser extends AbstractParser<ParseContext, NT, T> {
}
protected initCtx(): ParseContext {
- return {};
+ return {instrs: [], labels: {}, labelQueue: []};
}
protected parseLine(ctx: ParseContext,
parseTree: ParseTree<NT, T>,
line: Line<T>): void {
+ const what = parseTree.children[0];
+
+ switch (what.token) {
+ case 'label':
+ ctx.labelQueue = ctx.labelQueue.concat(this.parseLabels(what));
+ break;
+
+ case 'instr':
+ ctx.labelQueue = ctx.labelQueue.concat(
+ this.parseLabels(what.children[0]));
+
+ const word = what.children[1];
+ const op = (word.val as string).toLowerCase();
+
+ let operands: (RegisterOperand|IntegerOperand|LabelOperand)[];
+ if (what.children.length === 3) {
+ const instrOperands = what.children[2];
+ operands = this.parseInstrOperands(instrOperands);
+ } else {
+ operands = [];
+ }
+
+ ctx.instrs.push({kind: 'instr', line: line.num, op, operands});
+ this.popLabels(ctx);
+ break;
+
+ case 'pseudoop-line':
+ ctx.labelQueue = ctx.labelQueue.concat(
+ this.parseLabels(what.children[0]));
+
+ const pseudoop = what.children[1];
+ const opName = (pseudoop.val as string).slice(1).toLowerCase();
+ const operand = (what.children.length === 3)
+ ? (this.parseOperand(what.children[2]) as (IntegerOperand|LabelOperand))
+ : undefined;
+
+ ctx.instrs.push({kind: 'pseudoop', line: line.num, op: opName,
+ operand});
+ this.popLabels(ctx);
+ break;
+ }
}
protected finish(ctx: ParseContext): ParsedAssembly {
- return {sections: [], labels: {}};
+ if (ctx.labelQueue.length > 0) {
+ // TODO: line numbers
+ throw new Error(`stray label ${ctx.labelQueue[0]} at end of file`);
+ }
+
+ const asm: ParsedAssembly = {sections: [{startAddr: 0, instructions: ctx.instrs}], labels: {}};
+ Object.keys(ctx.labels).forEach(
+ label => { asm.labels[label] = [0, ctx.labels[label]]; });
+ return asm;
+ }
+
+ private popLabels(ctx: ParseContext): void {
+ while (ctx.labelQueue.length > 0) {
+ const label = ctx.labelQueue.pop() as string;
+ // TODO: detect dupe labels
+ ctx.labels[label] = ctx.instrs.length - 1;
+ }
+ }
+
+ private parseLabels(label: ParseTree<NT, T>): string[] {
+ if (label.children.length === 0) {
+ return [];
+ } else {
+ // Left recursion
+ const more = this.parseLabels(label.children[0]);
+ more.push(label.children[1].val as string);
+ return more;
+ }
+ }
+
+ private parseInstrOperands(instrOperands: ParseTree<NT, T>):
+ (RegisterOperand|IntegerOperand|LabelOperand)[] {
+ const operand = (instrOperands.children.length === 1)
+ ? instrOperands.children[0]
+ : instrOperands.children[2];
+ const parsedOperand = this.parseOperand(operand);
+
+ if (instrOperands.children.length === 1) {
+ return [parsedOperand];
+ } else {
+ const instrOperands2 = instrOperands.children[0];
+ const operands = this.parseInstrOperands(instrOperands2);
+ operands.push(parsedOperand);
+ return operands;
+ }
+ }
+
+ private parseOperand(operand: ParseTree<NT, T>):
+ RegisterOperand|IntegerOperand|LabelOperand {
+ const what = operand.children[0];
+ let val = what.val as string;
+
+ switch (what.token) {
+ case 'word':
+ return {kind: 'label', label: val};
+
+ case 'int-dec':
+ return {kind: 'int', val: parseInt(val, 10)};
+
+ case 'int-hex':
+ return {kind: 'int', val: parseInt(val.slice(2), 16)};
+
+ case 'reg':
+ val = val.toLowerCase();
+ const prefix = val.charAt(0);
+ const alias = val.slice(1);
+ const regno = /^\d+$/.test(alias)
+ ? parseInt(alias, 10)
+ // TODO: handle invalid aliases
+ : getAliases(this.isa, prefix)[alias];
+ return {kind: 'reg', prefix, num: regno};
+
+ case 'char':
+ return {kind: 'int', val: val.charCodeAt(0)};
+
+ default:
+ throw new Error(`unrecognized operand type \`${what.token}'`);
+ }
}
}
diff --git a/novice/assembler/parsers/tables/lc2200.ts b/novice/assembler/parsers/tables/lc2200.ts
index 0e0a49c..b13136d 100644
--- a/novice/assembler/parsers/tables/lc2200.ts
+++ b/novice/assembler/parsers/tables/lc2200.ts
@@ -2,5 +2,5 @@
// WARNING: GENERATED CODE by generate-parse-table.sh
import { ParseTable } from '../../lr1';
import { NT, T } from '../grammars/lc2200';
-const table: ParseTable<NT, T> = {"positions":{"(":0,")":1,",":2,":":3,"char":4,"eof":5,"int-dec":6,"int-hex":7,"pseudoop":8,"reg":9,"word":10,"instr":0,"instr-operands":1,"label":2,"line":3,"operand":4,"pseudoop-line":5,"pseudoop-operand":6},"actionTable":[[null,null,null,null,null,{"action":"reduce","production":{"lhs":"label","rhs":[]}},null,null,{"action":"reduce","production":{"lhs":"label","rhs":[]}},null,{"action":"reduce","production":{"lhs":"label","rhs":[]}}],[null,null,null,null,null,{"action":"accept","production":{"lhs":"line","rhs":["label"]}},null,null,{"action":"shift","newState":5},null,{"action":"shift","newState":4}],[null,null,null,null,null,{"action":"accept","production":{"lhs":"line","rhs":["instr"]}},null,null,null,null,null],[null,null,null,null,null,{"action":"accept","production":{"lhs":"line","rhs":["pseudoop-line"]}},null,null,null,null,null],[null,null,null,{"action":"shift","newState":11},null,null,{"action":"shift","newState":15},{"action":"shift","newState":16},null,{"action":"shift","newState":17},{"action":"shift","newState":14}],[null,null,null,null,{"action":"shift","newState":10},{"action":"reduce","production":{"lhs":"pseudoop-line","rhs":["label","pseudoop"]}},{"action":"shift","newState":8},{"action":"shift","newState":9},null,null,{"action":"shift","newState":7}],[null,null,null,null,null,{"action":"reduce","production":{"lhs":"pseudoop-line","rhs":["label","pseudoop","pseudoop-operand"]}},null,null,null,null,null],[null,null,null,null,null,{"action":"reduce","production":{"lhs":"pseudoop-operand","rhs":["word"]}},null,null,null,null,null],[null,null,null,null,null,{"action":"reduce","production":{"lhs":"pseudoop-operand","rhs":["int-dec"]}},null,null,null,null,null],[null,null,null,null,null,{"action":"reduce","production":{"lhs":"pseudoop-operand","rhs":["int-hex"]}},null,null,null,null,null],[null,null,null,null,null,{"action":"reduce","production":{"lhs":"pseudoop-operand","rhs":["char"]}},null,null,null,null,null],[null,null,null,null,null,{"action":"reduce","production":{"lhs":"label","rhs":["label","word",":"]}},null,null,{"action":"reduce","production":{"lhs":"label","rhs":["label","word",":"]}},null,{"action":"reduce","production":{"lhs":"label","rhs":["label","word",":"]}}],[{"action":"shift","newState":19},null,{"action":"shift","newState":18},null,null,{"action":"reduce","production":{"lhs":"instr","rhs":["label","word","instr-operands"]}},null,null,null,null,null],[{"action":"reduce","production":{"lhs":"instr-operands","rhs":["operand"]}},null,{"action":"reduce","production":{"lhs":"instr-operands","rhs":["operand"]}},null,null,{"action":"reduce","production":{"lhs":"instr-operands","rhs":["operand"]}},null,null,null,null,null],[{"action":"reduce","production":{"lhs":"operand","rhs":["word"]}},null,{"action":"reduce","production":{"lhs":"operand","rhs":["word"]}},null,null,{"action":"reduce","production":{"lhs":"operand","rhs":["word"]}},null,null,null,null,null],[{"action":"reduce","production":{"lhs":"operand","rhs":["int-dec"]}},null,{"action":"reduce","production":{"lhs":"operand","rhs":["int-dec"]}},null,null,{"action":"reduce","production":{"lhs":"operand","rhs":["int-dec"]}},null,null,null,null,null],[{"action":"reduce","production":{"lhs":"operand","rhs":["int-hex"]}},null,{"action":"reduce","production":{"lhs":"operand","rhs":["int-hex"]}},null,null,{"action":"reduce","production":{"lhs":"operand","rhs":["int-hex"]}},null,null,null,null,null],[{"action":"reduce","production":{"lhs":"operand","rhs":["reg"]}},null,{"action":"reduce","production":{"lhs":"operand","rhs":["reg"]}},null,null,{"action":"reduce","production":{"lhs":"operand","rhs":["reg"]}},null,null,null,null,null],[null,null,null,null,null,null,{"action":"shift","newState":15},{"action":"shift","newState":16},null,{"action":"shift","newState":17},{"action":"shift","newState":14}],[null,null,null,null,null,null,{"action":"shift","newState":22},{"action":"shift","newState":23},null,{"action":"shift","newState":24},{"action":"shift","newState":21}],[null,{"action":"shift","newState":25},null,null,null,null,null,null,null,null,null],[null,{"action":"reduce","production":{"lhs":"operand","rhs":["word"]}},null,null,null,null,null,null,null,null,null],[null,{"action":"reduce","production":{"lhs":"operand","rhs":["int-dec"]}},null,null,null,null,null,null,null,null,null],[null,{"action":"reduce","production":{"lhs":"operand","rhs":["int-hex"]}},null,null,null,null,null,null,null,null,null],[null,{"action":"reduce","production":{"lhs":"operand","rhs":["reg"]}},null,null,null,null,null,null,null,null,null],[{"action":"reduce","production":{"lhs":"instr-operands","rhs":["instr-operands","(","operand",")"]}},null,{"action":"reduce","production":{"lhs":"instr-operands","rhs":["instr-operands","(","operand",")"]}},null,null,{"action":"reduce","production":{"lhs":"instr-operands","rhs":["instr-operands","(","operand",")"]}},null,null,null,null,null],[{"action":"reduce","production":{"lhs":"instr-operands","rhs":["instr-operands",",","operand"]}},null,{"action":"reduce","production":{"lhs":"instr-operands","rhs":["instr-operands",",","operand"]}},null,null,{"action":"reduce","production":{"lhs":"instr-operands","rhs":["instr-operands",",","operand"]}},null,null,null,null,null]],"gotoTable":[[2,null,1,null,null,3,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,12,null,null,13,null,null],[null,null,null,null,null,null,6],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,26,null,null],[null,null,null,null,20,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null]]};
+const table: ParseTable<NT, T> = {"positions":{"(":0,")":1,",":2,":":3,"char":4,"eof":5,"int-dec":6,"int-hex":7,"pseudoop":8,"reg":9,"word":10,"instr":0,"instr-operands":1,"label":2,"line":3,"operand":4,"pseudoop-line":5,"pseudoop-operand":6},"actionTable":[[null,null,null,null,null,{"action":"reduce","production":{"lhs":"label","rhs":[]}},null,null,{"action":"reduce","production":{"lhs":"label","rhs":[]}},null,{"action":"reduce","production":{"lhs":"label","rhs":[]}}],[null,null,null,null,null,{"action":"accept","production":{"lhs":"line","rhs":["label"]}},null,null,{"action":"shift","newState":5},null,{"action":"shift","newState":4}],[null,null,null,null,null,{"action":"accept","production":{"lhs":"line","rhs":["instr"]}},null,null,null,null,null],[null,null,null,null,null,{"action":"accept","production":{"lhs":"line","rhs":["pseudoop-line"]}},null,null,null,null,null],[null,null,null,{"action":"shift","newState":11},null,{"action":"reduce","production":{"lhs":"instr","rhs":["label","word"]}},{"action":"shift","newState":15},{"action":"shift","newState":16},null,{"action":"shift","newState":17},{"action":"shift","newState":14}],[null,null,null,null,{"action":"shift","newState":10},{"action":"reduce","production":{"lhs":"pseudoop-line","rhs":["label","pseudoop"]}},{"action":"shift","newState":8},{"action":"shift","newState":9},null,null,{"action":"shift","newState":7}],[null,null,null,null,null,{"action":"reduce","production":{"lhs":"pseudoop-line","rhs":["label","pseudoop","pseudoop-operand"]}},null,null,null,null,null],[null,null,null,null,null,{"action":"reduce","production":{"lhs":"pseudoop-operand","rhs":["word"]}},null,null,null,null,null],[null,null,null,null,null,{"action":"reduce","production":{"lhs":"pseudoop-operand","rhs":["int-dec"]}},null,null,null,null,null],[null,null,null,null,null,{"action":"reduce","production":{"lhs":"pseudoop-operand","rhs":["int-hex"]}},null,null,null,null,null],[null,null,null,null,null,{"action":"reduce","production":{"lhs":"pseudoop-operand","rhs":["char"]}},null,null,null,null,null],[null,null,null,null,null,{"action":"reduce","production":{"lhs":"label","rhs":["label","word",":"]}},null,null,{"action":"reduce","production":{"lhs":"label","rhs":["label","word",":"]}},null,{"action":"reduce","production":{"lhs":"label","rhs":["label","word",":"]}}],[{"action":"shift","newState":19},null,{"action":"shift","newState":18},null,null,{"action":"reduce","production":{"lhs":"instr","rhs":["label","word","instr-operands"]}},null,null,null,null,null],[{"action":"reduce","production":{"lhs":"instr-operands","rhs":["operand"]}},null,{"action":"reduce","production":{"lhs":"instr-operands","rhs":["operand"]}},null,null,{"action":"reduce","production":{"lhs":"instr-operands","rhs":["operand"]}},null,null,null,null,null],[{"action":"reduce","production":{"lhs":"operand","rhs":["word"]}},null,{"action":"reduce","production":{"lhs":"operand","rhs":["word"]}},null,null,{"action":"reduce","production":{"lhs":"operand","rhs":["word"]}},null,null,null,null,null],[{"action":"reduce","production":{"lhs":"operand","rhs":["int-dec"]}},null,{"action":"reduce","production":{"lhs":"operand","rhs":["int-dec"]}},null,null,{"action":"reduce","production":{"lhs":"operand","rhs":["int-dec"]}},null,null,null,null,null],[{"action":"reduce","production":{"lhs":"operand","rhs":["int-hex"]}},null,{"action":"reduce","production":{"lhs":"operand","rhs":["int-hex"]}},null,null,{"action":"reduce","production":{"lhs":"operand","rhs":["int-hex"]}},null,null,null,null,null],[{"action":"reduce","production":{"lhs":"operand","rhs":["reg"]}},null,{"action":"reduce","production":{"lhs":"operand","rhs":["reg"]}},null,null,{"action":"reduce","production":{"lhs":"operand","rhs":["reg"]}},null,null,null,null,null],[null,null,null,null,null,null,{"action":"shift","newState":15},{"action":"shift","newState":16},null,{"action":"shift","newState":17},{"action":"shift","newState":14}],[null,null,null,null,null,null,{"action":"shift","newState":22},{"action":"shift","newState":23},null,{"action":"shift","newState":24},{"action":"shift","newState":21}],[null,{"action":"shift","newState":25},null,null,null,null,null,null,null,null,null],[null,{"action":"reduce","production":{"lhs":"operand","rhs":["word"]}},null,null,null,null,null,null,null,null,null],[null,{"action":"reduce","production":{"lhs":"operand","rhs":["int-dec"]}},null,null,null,null,null,null,null,null,null],[null,{"action":"reduce","production":{"lhs":"operand","rhs":["int-hex"]}},null,null,null,null,null,null,null,null,null],[null,{"action":"reduce","production":{"lhs":"operand","rhs":["reg"]}},null,null,null,null,null,null,null,null,null],[{"action":"reduce","production":{"lhs":"instr-operands","rhs":["instr-operands","(","operand",")"]}},null,{"action":"reduce","production":{"lhs":"instr-operands","rhs":["instr-operands","(","operand",")"]}},null,null,{"action":"reduce","production":{"lhs":"instr-operands","rhs":["instr-operands","(","operand",")"]}},null,null,null,null,null],[{"action":"reduce","production":{"lhs":"instr-operands","rhs":["instr-operands",",","operand"]}},null,{"action":"reduce","production":{"lhs":"instr-operands","rhs":["instr-operands",",","operand"]}},null,null,{"action":"reduce","production":{"lhs":"instr-operands","rhs":["instr-operands",",","operand"]}},null,null,null,null,null]],"gotoTable":[[2,null,1,null,null,3,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,12,null,null,13,null,null],[null,null,null,null,null,null,6],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,26,null,null],[null,null,null,null,20,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null],[null,null,null,null,null,null,null]]};
export default table;
diff --git a/novice/isa/index.ts b/novice/isa/index.ts
index 638f5b4..a59380f 100644
--- a/novice/isa/index.ts
+++ b/novice/isa/index.ts
@@ -1,6 +1,6 @@
import { DummyIsa } from './dummy';
import { IO, StreamIO } from './io';
-import { Fields, Instruction, Isa, Reg, regPrefixes } from './isa';
+import { Fields, getAliases, Instruction, Isa, Reg, regPrefixes } from './isa';
import { Lc2200Isa } from './lc2200';
import { Lc3Isa } from './lc3';
import { MachineState, MachineStateUpdate, RegIdentifier } from './state';
@@ -20,4 +20,5 @@ function getIsa(isaName: string): Isa {
}
export { Isa, Instruction, isas, Lc3Isa, MachineState, MachineStateUpdate,
- RegIdentifier, Fields, Reg, getIsa, IO, StreamIO, regPrefixes };
+ RegIdentifier, Fields, Reg, getIsa, IO, StreamIO, regPrefixes,
+ getAliases };
diff --git a/novice/isa/isa.ts b/novice/isa/isa.ts
index 0c843a6..f15caf0 100644
--- a/novice/isa/isa.ts
+++ b/novice/isa/isa.ts
@@ -27,6 +27,7 @@ interface RegRange {
prefix: string;
sext: boolean;
bits: number;
+ aliases?: {[s: string]: number};
}
type Reg = RegSolo|RegRange;
@@ -82,4 +83,14 @@ function regPrefixes(isa: Isa): string[] {
return result;
}
-export { Isa, Fields, Instruction, Reg, regPrefixes };
+function getAliases(isa: Isa, prefix: string): {[s: string]: number} {
+ for (const reg of isa.regs) {
+ if (reg.kind === 'reg-range' && reg.prefix === prefix) {
+ return reg.aliases || {};
+ }
+ }
+
+ throw new Error(`no such register prefix ${prefix}`);
+}
+
+export { Isa, Fields, Instruction, Reg, regPrefixes, getAliases };
diff --git a/novice/isa/lc2200.ts b/novice/isa/lc2200.ts
index 33a5564..e8cf841 100644
--- a/novice/isa/lc2200.ts
+++ b/novice/isa/lc2200.ts
@@ -33,7 +33,11 @@ const Lc2200Isa: Isa = {
addressability: 32,
},
regs: [
- {kind: 'reg-range', count: 16, prefix: '$', sext: true, bits: 32},
+ {kind: 'reg-range', count: 16, prefix: '$', sext: true, bits: 32,
+ aliases: {zero: 0, at: 1, v0: 2, a0: 3,
+ a1: 4, a2: 5, t0: 6, t1: 7,
+ t2: 8, s0: 9, s1: 10, s2: 11,
+ k0: 12, sp: 13, fp: 14, ra: 15}},
],
instructions: [
{op: 'add', fields: [