Mercurial > lcfOS
changeset 357:818be710e13d
Added acceptance function to burg
author | Windel Bouwman |
---|---|
date | Fri, 14 Mar 2014 15:14:29 +0100 |
parents | 52492b304adf |
children | 5ef1cb1bb54f |
files | doc/compiler.rst kernel/kernel.c3 python/baselex.py python/burg.x python/ppci/target/arm/__init__.py python/ppci/target/arm/arm.brg python/ppci/target/thumb/arm.brg python/pyburg.py test/sample4.brg |
diffstat | 9 files changed, 89 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/compiler.rst Fri Mar 14 13:02:16 2014 +0100 +++ b/doc/compiler.rst Fri Mar 14 15:14:29 2014 +0100 @@ -77,14 +77,27 @@ The back-end is more complicated. There are several steps to be taken here. -1. Instruction selection -2. register allocation -3. Peep hole optimization? -4. real code generation +1. Canonicalization +2. Tree creation +3. Instruction selection +4. register allocation +5. Instruction emission +6. TODO: Peep hole optimization? .. automodule:: ppci.codegen :members: +Canonicalize +~~~~~~~~~~~~ + +During this phase, the IR-code is made simpler. Function calls are pulled pulled +to top level and the frame pointer is introduced. + +Tree building +~~~~~~~~~~~~~ + +From IR-code a tree is generated which can be used to select instructions. + Instruction selection ~~~~~~~~~~~~~~~~~~~~~ @@ -97,3 +110,9 @@ // .. autoclass:: ppci.irmach.AbstractInstruction +Register allocation +~~~~~~~~~~~~~~~~~~~ + +The selected instructions are used to select correct registers. + +
--- a/kernel/kernel.c3 Fri Mar 14 13:02:16 2014 +0100 +++ b/kernel/kernel.c3 Fri Mar 14 15:14:29 2014 +0100 @@ -14,7 +14,7 @@ io.println("Welcome to lcfos!"); // io.print_int(0x1337); - process.init(); + // process.init(); //memory:init(); //Process proc = new process:Process();
--- a/python/baselex.py Fri Mar 14 13:02:16 2014 +0100 +++ b/python/baselex.py Fri Mar 14 15:14:29 2014 +0100 @@ -1,6 +1,6 @@ import re -from ppci import Token +from ppci import Token, CompilerError def tokenize(tok_spec, txt): tok_re = '|'.join('(?P<{}>{})'.format(pair[0], pair[1]) for pair in tok_spec) @@ -21,4 +21,4 @@ pos = mo.end() mo = gettok(line, pos) if len(line) != pos: - raise ParserException('Lex fault at {}'.format(line[pos:])) + raise CompilerError('Lex fault at {}'.format(line[pos:]))
--- a/python/burg.x Fri Mar 14 13:02:16 2014 +0100 +++ b/python/burg.x Fri Mar 14 15:14:29 2014 +0100 @@ -1,5 +1,5 @@ -%tokens ':' ';' '(' ')' ',' template id number '%%' '%terminal' header +%tokens ':' ';' '(' ')' ',' string id number '%%' '%terminal' header %% @@ -20,7 +20,8 @@ rules: | rules rule; -rule: id ':' tree cost template { self.system.add_rule($1.val, $3, $4, $5.val) }; +rule: id ':' tree cost string { self.system.add_rule($1.val, $3, $4, None, $5.val) }; +rule: id ':' tree cost string string { self.system.add_rule($1.val, $3, $4, $5.val, $6.val) }; cost: number { return $1.val };
--- a/python/ppci/target/arm/__init__.py Fri Mar 14 13:02:16 2014 +0100 +++ b/python/ppci/target/arm/__init__.py Fri Mar 14 15:14:29 2014 +0100 @@ -4,7 +4,7 @@ from ..arm.registers import R8, R9, R10, R11, R12, SP, LR, PC from ..arm.registers import register_range -from .instructions import Dcd, Mov, Add, Sub, Orr1, Mul, Mov2, Add1, Mul1 +from .instructions import Dcd, Mov, Mov1, Add, Sub, Orr1, Mul, Mov2, Add1, Mul1 from .instructions import Lsr1, Lsl1, And1, Sub1 from .instructions import B, Bl, Ble, Bgt, Beq, Blt, Cmp, Cmp2 from .instructions import Push, Pop, Str, Ldr, Ldr3, Str1, Ldr1, Adr @@ -29,6 +29,7 @@ self.add_lowering(Mul1, lambda im: Mul1(im.dst[0], im.src[0], im.src[1])) self.add_lowering(Lsr1, lambda im: Lsr1(im.dst[0], im.src[0], im.src[1])) self.add_lowering(And1, lambda im: And1(im.dst[0], im.src[0], im.src[1])) + self.add_lowering(Mov1, lambda im: Mov1(im.dst[0], im.others[0])) def make_parser(self): # Assembly grammar:
--- a/python/ppci/target/arm/arm.brg Fri Mar 14 13:02:16 2014 +0100 +++ b/python/ppci/target/arm/arm.brg Fri Mar 14 15:14:29 2014 +0100 @@ -1,7 +1,7 @@ from ppci.target.arm.instructions import Add1, Sub1, Mul1 from ppci.target.arm.instructions import Ldr1, Ldr3, Adr -from ppci.target.arm.instructions import And1, Lsr1, Lsl1 +from ppci.target.arm.instructions import And1, Lsr1, Lsl1, Mov1 %% @@ -12,22 +12,25 @@ %% -reg: ADDI32(reg, reg) 2 (. d = self.newTmp(); self.emit(Add1, dst=[d], src=[$1, $2]); return d .) -reg: SUBI32(reg, reg) 2 (. d = self.newTmp(); self.emit(Sub1, dst=[d], src=[$1, $2]); return d .) -reg: MULI32(reg, reg) 2 (. d = self.newTmp(); self.emit(Mul1, dst=[d], src=[$1, $2]); return d .) -reg: ANDI32(reg, reg) 2 (. d = self.newTmp(); self.emit(And1, dst=[d], src=[$1, $2]); return d .) -reg: SHRI32(reg, reg) 2 (. d = self.newTmp(); self.emit(Lsr1, dst=[d], src=[$1, $2]); return d .) +reg: ADDI32(reg, reg) 2 'd = self.newTmp(); self.emit(Add1, dst=[d], src=[c0, c1]); return d' +reg: SUBI32(reg, reg) 2 'd = self.newTmp(); self.emit(Sub1, dst=[d], src=[c0, c1]); return d' +reg: MULI32(reg, reg) 2 'd = self.newTmp(); self.emit(Mul1, dst=[d], src=[c0, c1]); return d' +reg: ANDI32(reg, reg) 2 'd = self.newTmp(); self.emit(And1, dst=[d], src=[c0, c1]); return d' +reg: SHRI32(reg, reg) 2 'd = self.newTmp(); self.emit(Lsr1, dst=[d], src=[c0, c1]); return d' -reg: MEMI32(ADDI32(reg, cn)) 2 (. d = self.newTmp(); self.emit(Ldr1, dst=[d], src=[$1], others=[$2]); return d .) -reg: MEMI32(reg) 2 (. d = self.newTmp(); self.emit(Ldr1, dst=[d], src=[$1], others=[0]); return d .) +reg: MEMI32(ADDI32(reg, cn)) 2 'd = self.newTmp(); self.emit(Ldr1, dst=[d], src=[c0], others=[c1]); return d' +reg: MEMI32(reg) 2 'd = self.newTmp(); self.emit(Ldr1, dst=[d], src=[c0], others=[0]); return d' -cn: CONSTI32 0 (. return $$.value .) +cn: CONSTI32 0 'return tree.value' -reg: CONSTI32 3 (. d = self.newTmp(); ln = self.selector.frame.add_constant($$.value); self.emit(Ldr3, dst=[d], others=[ln]); return d .) +reg: CONSTI32 6 'd = self.newTmp(); ln = self.selector.frame.add_constant(tree.value); self.emit(Ldr3, dst=[d], others=[ln]); return d' + +reg: CONSTI32 2 'return (type(tree.value) is int) and (tree.value < 256)' 'd = self.newTmp(); self.emit(Mov1, dst=[d], others=[tree.value]); return d' -reg: ADR(CONSTDATA) 2 (. d = self.newTmp(); ln = self.selector.frame.add_constant($$.children[0].value); self.emit(Adr, dst=[d], others=[ln]); return d .) +reg: ADR(CONSTDATA) 2 'd = self.newTmp(); ln = self.selector.frame.add_constant(tree.children[0].value); self.emit(Adr, dst=[d], others=[ln]); return d' -reg: REGI32 1 (. return $$.value .) +reg: REGI32 1 'return tree.value' -reg: CALL 1 (. return self.selector.munchCall($$.value) .) +reg: CALL 1 'return self.selector.munchCall(tree.value)' +
--- a/python/ppci/target/thumb/arm.brg Fri Mar 14 13:02:16 2014 +0100 +++ b/python/ppci/target/thumb/arm.brg Fri Mar 14 15:14:29 2014 +0100 @@ -14,18 +14,18 @@ %% -reg: ADDI32(reg, reg) 2 (. d = self.newTmp(); self.emit(Add3, dst=[d], src=[$1, $2]); return d .) -reg: SUBI32(reg, reg) 2 (. d = self.newTmp(); self.emit(Sub3, dst=[d], src=[$1, $2]); return d .) -reg: ORI32(reg, reg) 2 (. d = self.newTmp(); self.selector.move(d, $1); self.emit(Orr, dst=[], src=[d, $2]); return d .) -reg: SHLI32(reg, reg) 2 (. d = self.newTmp(); self.selector.move(d, $1); self.emit(Lsl, dst=[], src=[d, $2]); return d .) -reg: MULI32(reg, reg) 2 (. d = self.newTmp(); self.selector.move(d, $1); self.emit(Mul, dst=[d], src=[$2, d]); return d .) +reg: ADDI32(reg, reg) 2 'd = self.newTmp(); self.emit(Add3, dst=[d], src=[c0, c1]); return d' +reg: SUBI32(reg, reg) 2 'd = self.newTmp(); self.emit(Sub3, dst=[d], src=[c0, c1]); return d' +reg: ORI32(reg, reg) 2 'd = self.newTmp(); self.selector.move(d, c0); self.emit(Orr, dst=[], src=[d, c1]); return d' +reg: SHLI32(reg, reg) 2 'd = self.newTmp(); self.selector.move(d, c0); self.emit(Lsl, dst=[], src=[d, c1]); return d' +reg: MULI32(reg, reg) 2 'd = self.newTmp(); self.selector.move(d, c0); self.emit(Mul, dst=[d], src=[c1, d]); return d' -reg: CONSTI32 3 (. d = self.newTmp(); ln = self.selector.frame.addConstant($$.value); self.emit(Ldr3, dst=[d], others=[ln]); return d .) -reg: MEMI32(reg) 4 (. d = self.newTmp(); self.emit(Ldr2, dst=[d], src=[$1], others=[0]); return d .) -reg: REGI32 1 (. return $$.value .) -reg: CALL 1 (. return self.selector.munchCall($$.value) .) +reg: CONSTI32 3 'd = self.newTmp(); ln = self.selector.frame.addConstant(tree.value); self.emit(Ldr3, dst=[d], others=[ln]); return d' +reg: MEMI32(reg) 4 'd = self.newTmp(); self.emit(Ldr2, dst=[d], src=[c0], others=[0]); return d' +reg: REGI32 1 'return tree.value' +reg: CALL 1 'return self.selector.munchCall(tree.value)' -stmt: MOVI32(MEMI32(addr), reg) 3 (. self.emit(Str2, src=[$1, $2]) .) +stmt: MOVI32(MEMI32(addr), reg) 3 'self.emit(Str2, src=[c0, c1])' -addr: reg 2 (. .) +addr: reg 0 ''
--- a/python/pyburg.py Fri Mar 14 13:02:16 2014 +0100 +++ b/python/pyburg.py Fri Mar 14 15:14:29 2014 +0100 @@ -76,8 +76,7 @@ ('id', r'[A-Za-z][A-Za-z\d_]*', lambda typ, val: (typ, val)), ('kw', r'%[A-Za-z][A-Za-z\d_]*', lambda typ, val: (val, val)), ('number', r'\d+', lambda typ, val: (typ, int(val))), - ('STRING', r"'[^']*'", lambda typ, val: ('id', val[1:-1])), - ('template', r"\(\..*\.\)", lambda typ, val: (typ, val)), + ('STRING', r"'[^']*'", lambda typ, val: ('string', val[1:-1])), ('OTHER', r'[:;\|\(\),]', lambda typ, val: (val, val)), ('SKIP', r'[ ]', None) ] @@ -115,10 +114,11 @@ class Rule: """ A rewrite rule. Specifies a tree that can be rewritten into a result at a specific cost """ - def __init__(self, non_term, tree, cost, template): + def __init__(self, non_term, tree, cost, acceptance, template): self.non_term = non_term self.tree = tree self.cost = cost + self.acceptance = acceptance self.template = template self.nr = 0 @@ -154,11 +154,11 @@ non_terminals = property(lambda s: s.symType(Nonterm)) - def add_rule(self, non_term, tree, cost, template): - template = template[2:-2].strip() + def add_rule(self, non_term, tree, cost, acceptance, template): + template = template.strip() if not template: template = 'pass' - rule = Rule(non_term, tree, cost, template) + rule = Rule(non_term, tree, cost, acceptance, template) if len(tree.children) == 0 and tree.name not in self.terminals: self.non_term(tree.name).chain_rules.append(rule) self.non_term(rule.non_term) @@ -231,28 +231,35 @@ self.print() for rule in self.system.rules: if rule.num_nts > 0: - args = ', ' + ', '.join('nt{}'.format(x) for x in range(rule.num_nts)) + args = ', '.join('c{}'.format(x) for x in range(rule.num_nts)) + args = ', ' + args else: args = '' + # Create template function: self.print(' def P{}(self, tree{}):'.format(rule.nr, args)) template = rule.template - template = template.replace('$$', 'tree') - for i in range(rule.num_nts): - template = template.replace('${}'.format(i+1), 'nt{}'.format(i)) for t in template.split(';'): self.print(' {}'.format(t.strip())) + # Create acceptance function: + if rule.acceptance: + self.print(' def A{}(self, tree):'.format(rule.nr)) + for t in rule.acceptance.split(';'): + self.print(' {}'.format(t.strip())) self.emit_state() self.print(' def gen(self, tree):') self.print(' self.burm_label(tree)') self.print(' if not tree.state.has_goal("{}"):'.format(self.system.goal)) - self.print(' raise Exception("Tree {} not covered".format(tree))') + self.print(' raise Exception("Tree {} not covered".format(tree))') self.print(' return self.apply_rules(tree, "{}")'.format(self.system.goal)) def emit_record(self, rule, state_var): # TODO: check for rules fullfilled (by not using 999999) + acc = '' + if rule.acceptance: + acc = ' and self.A{}(tree)'.format(rule.nr) self.print(' nts = self.nts({})'.format(rule.nr)) self.print(' kids = self.kids(tree, {})'.format(rule.nr)) - self.print(' if all(x.state.has_goal(y) for x, y in zip(kids, nts)):') + self.print(' if all(x.state.has_goal(y) for x, y in zip(kids, nts)){}:'.format(acc)) self.print(' c = sum(x.state.get_cost(y) for x, y in zip(kids, nts)) + {}'.format(rule.cost)) self.print(' tree.state.set_cost("{}", c, {})'.format(rule.non_term, rule.nr)) for cr in self.system.symbols[rule.non_term].chain_rules:
--- a/test/sample4.brg Fri Mar 14 13:02:16 2014 +0100 +++ b/test/sample4.brg Fri Mar 14 15:14:29 2014 +0100 @@ -6,17 +6,17 @@ %% -stmt: ASGNI(disp, reg) 1 (. self.tr(1) .) -stmt: reg 0 (. self.tr(2).) -reg: ADDI(reg, rc) 1 (. self.tr(3) .) -reg: CVCI(INDIRC(disp)) 1 (. self.tr(4) .) -reg: IOI 0 (. self.tr(5).) -reg: disp 1 (. self.tr(6).) -disp: ADDI(reg, con) 1 (. self.tr(7).) -disp: ADDRLP 0 (. self.tr(8).) -rc: con 0 (. self.tr(9).) -rc: reg 0 (. self.tr(10).) -con: CNSTI 0 (. self.tr(11).) -con: IOI 0 (. self.tr(12).) +stmt: ASGNI(disp, reg) 1 'self.tr(1) ' +stmt: reg 0 ' self.tr(2)' +reg: ADDI(reg, rc) 1 'self.tr(3) ' +reg: CVCI(INDIRC(disp)) 1 'self.tr(4) ' +reg: IOI 0 'self.tr(5)' +reg: disp 1 'self.tr(6)' +disp: ADDI(reg, con) 1 'self.tr(7)' +disp: ADDRLP 0 ' self.tr(8)' +rc: con 0 ' self.tr(9)' +rc: reg 0 'self.tr(10)' +con: CNSTI 0 ' self.tr(11)' +con: IOI 0 ' self.tr(12)'