Mercurial > lcfOS
changeset 354:5477e499b039
Added some sort of string functionality
author | Windel Bouwman |
---|---|
date | Thu, 13 Mar 2014 18:59:06 +0100 |
parents | b8ad45b3a573 |
children | c2ddc8a36f5e |
files | kernel/arch/vexpressA9.c3 kernel/kernel.c3 kernel/make.sh kernel/monitor.sh kernel/qemutst.sh python/ppci/buildtasks.py python/ppci/c3/astnodes.py python/ppci/c3/builder.py python/ppci/c3/codegenerator.py python/ppci/c3/grammar.txt python/ppci/c3/parser.py python/ppci/c3/scope.py python/ppci/c3/visitor.py python/ppci/codegen/canon.py python/ppci/ir.py python/ppci/ir2tree.py python/ppci/linker.py python/ppci/target/arm/__init__.py python/ppci/target/arm/arm.brg python/ppci/target/arm/frame.py python/ppci/target/arm/instructions.py python/ppci/target/basetarget.py python/pyburg.py test/testarmasm.py test/testc3.py test/testemulation.py util/test_patterns.txt |
diffstat | 27 files changed, 310 insertions(+), 70 deletions(-) [+] |
line wrap: on
line diff
--- a/kernel/arch/vexpressA9.c3 Sun Mar 09 18:49:10 2014 +0100 +++ b/kernel/arch/vexpressA9.c3 Thu Mar 13 18:59:06 2014 +0100 @@ -2,7 +2,7 @@ function void init() { - putc(0x65) + // putc(65) } function void putc(int c)
--- a/kernel/kernel.c3 Sun Mar 09 18:49:10 2014 +0100 +++ b/kernel/kernel.c3 Thu Mar 13 18:59:06 2014 +0100 @@ -21,26 +21,14 @@ while(true) {} } -function int strlen(string txt) -{ - -} - -function int getchar(string txt, int index) -{ - if (index < strlen(txt)) - { - } -} - function void print(string txt) { var int i; i = 0; - while (i < strlen(txt)) + while (i < txt->len) { - arch.putc(getchar(txt, i)); + arch.putc(cast<int>(txt->txt[i])); i = i + 1; } }
--- a/kernel/make.sh Sun Mar 09 18:49:10 2014 +0100 +++ b/kernel/make.sh Thu Mar 13 18:59:06 2014 +0100 @@ -1,5 +1,5 @@ #!/bin/bash -../python/zcc.py recipe thumb.yaml +# ../python/zcc.py recipe thumb.yaml ../python/zcc.py --report log.txt recipe arm.yaml
--- a/kernel/monitor.sh Sun Mar 09 18:49:10 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -#!/bin/bash - -socat stdio UNIX-CONNECT:vm.sock
--- a/kernel/qemutst.sh Sun Mar 09 18:49:10 2014 +0100 +++ b/kernel/qemutst.sh Thu Mar 13 18:59:06 2014 +0100 @@ -7,8 +7,8 @@ echo "Trying to run test on stellaris qemu machine" # -S means halt at start: -qemu-system-arm -M vexpress-a9 -m 128M -kernel kernel.bin \ - -monitor unix:vm.sock,server -serial file:output.txt -S -s +qemu-system-arm -M vexpress-a9 -m 128M -kernel kernel_arm.bin \ + -serial stdio -s #sleep 1
--- a/python/ppci/buildtasks.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/buildtasks.py Thu Mar 13 18:59:06 2014 +0100 @@ -57,7 +57,8 @@ for ircode in c3b.build(self.sources, self.includes): if not ircode: - return + # Something went wrong, do not continue the code generation + continue d = {'ircode':ircode} self.logger.debug('Verifying code {}'.format(ircode), extra=d)
--- a/python/ppci/c3/astnodes.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/c3/astnodes.py Thu Mar 13 18:59:06 2014 +0100 @@ -125,6 +125,16 @@ return 'STRUCT' +class ArrayType(Type): + """ Array type """ + def __init__(self, element_type, size): + self.element_type = element_type + self.size = size + + def __repr__(self): + return 'ARRAY {}'.format(self.size) + + class DefinedType(NamedType): """ A named type indicating another type """ def __init__(self, name, typ, loc): @@ -225,6 +235,17 @@ return 'MEMBER {}.{}'.format(self.base, self.field) +class Index(Expression): + """ Index something, for example an array """ + def __init__(self, base, i, loc): + super().__init__(loc) + self.base = base + self.i = i + + def __repr__(self): + return 'Index {}'.format(self.i) + + class Unop(Expression): """ Operation on one operand """ def __init__(self, op, a, loc):
--- a/python/ppci/c3/builder.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/c3/builder.py Thu Mar 13 18:59:06 2014 +0100 @@ -130,4 +130,3 @@ yield self.cg.gencode(pkg) if not all(pkg.ok for pkg in all_pkgs): self.ok = False - return
--- a/python/ppci/c3/codegenerator.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/c3/codegenerator.py Thu Mar 13 18:59:06 2014 +0100 @@ -1,4 +1,5 @@ import logging +import struct from .. import ir from .. import irutils from . import astnodes as ast @@ -200,6 +201,8 @@ self.emit(ir.Jump(bbfalse)) else: raise NotImplementedError('Unknown cond {}'.format(expr)) + + # Check that the condition is a boolean value: if not self.equalTypes(expr.typ, self.boolType): self.error('Condition must be boolean', expr.loc) @@ -272,6 +275,23 @@ bt = self.the_type(expr.base.typ) offset = ir.Const(bt.fieldOffset(expr.field)) return ir.Mem(ir.Add(base.e, offset)) + elif type(expr) is ast.Index: + """ Array indexing """ + base = self.genExprCode(expr.base) + idx = self.genExprCode(expr.i) + base_typ = self.the_type(expr.base.typ) + if not isinstance(base_typ, ast.ArrayType): + raise SemanticError('Cannot index non-array type {}'.format(base_typ), expr.base.loc) + idx_type = self.the_type(expr.i.typ) + if not self.equalTypes(idx_type, self.intType): + raise SemanticError('Index must be int not {}'.format(idx_type), expr.i.loc) + assert type(base) is ir.Mem + element_type = self.the_type(base_typ.element_type) + element_size = self.size_of(element_type) + expr.typ = base_typ.element_type + expr.lvalue = True + + return ir.Mem(ir.Add(base.e, ir.Mul(idx, ir.Const(element_size)))) elif type(expr) is ast.Literal: expr.lvalue = False typemap = {int: 'int', float: 'double', bool: 'bool', str:'string'} @@ -279,7 +299,12 @@ expr.typ = self.pkg.scope[typemap[type(expr.val)]] else: raise SemanticError('Unknown literal type {}'.format(expr.val), expr.loc) - return ir.Const(expr.val) + # Construct correct const value: + if type(expr.val) is str: + cval = struct.pack('<I', len(expr.val)) + expr.val.encode('ascii') + return ir.Addr(ir.Const(cval)) + else: + return ir.Const(expr.val) elif type(expr) is ast.TypeCast: return self.gen_type_cast(expr) elif type(expr) is ast.FunctionCall: @@ -299,6 +324,10 @@ isinstance(to_type, ast.PointerType): expr.typ = expr.to_type return ar + elif type(from_type) is ast.BaseType and from_type.name == 'byte' and \ + type(to_type) is ast.BaseType and to_type.name == 'int': + expr.typ = expr.to_type + return ar else: raise SemanticError('Cannot cast {} to {}' .format(from_type, to_type), expr.loc) @@ -357,6 +386,8 @@ return t.bytesize elif type(t) is ast.StructureType: return sum(self.size_of(mem.typ) for mem in t.mems) + elif type(t) is ast.ArrayType: + return t.size * self.size_of(t.element_type) else: raise NotImplementedError(str(t)) @@ -395,6 +426,8 @@ return False return all(self.equalTypes(am.typ, bm.typ) for am, bm in zip(a.mems, b.mems)) + elif type(a) is ast.ArrayType: + return self.equalTypes(a.element_type, b.element_type) else: raise NotImplementedError('{} not implemented'.format(type(a))) return False
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/ppci/c3/grammar.txt Thu Mar 13 18:59:06 2014 +0100 @@ -0,0 +1,12 @@ + + +stmt: if_stmt | while_stmt | for_stmt | assign_stmt | compound_stmt + +compound_stmt: '{' stmt ';' stmt ... '}' +if_stmt: 'if' '(' cond ')' stmt +assign_stmt: lhs '=' expr + +cond: + +expr: +
--- a/python/ppci/c3/parser.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/c3/parser.py Thu Mar 13 18:59:06 2014 +0100 @@ -1,12 +1,12 @@ import logging -from ppci import CompilerError +from .. import CompilerError from .astnodes import Member, Literal, TypeCast, Unop, Binop from .astnodes import Assignment, ExpressionStatement, Compound from .astnodes import Return, While, If, Empty, For from .astnodes import FunctionType, Function, FormalParameter -from .astnodes import StructureType, DefinedType, PointerType +from .astnodes import StructureType, DefinedType, PointerType, ArrayType from .astnodes import Constant, Variable -from .astnodes import StructField, Deref +from .astnodes import StructField, Deref, Index from .astnodes import Package from .astnodes import Identifier from .astnodes import FunctionCall @@ -105,14 +105,29 @@ return ids # Type system - def parseTypeSpec(self): - # For now, do simple type spec, just parse an ID: + def PostFixId(self): + pfe = self.PrimaryExpression_Id() + while self.Peak in ['.']: + if self.hasConsumed('.'): + field = self.Consume('ID') + pfe = Member(pfe, field.val, field.loc) + else: + raise Exception() + return pfe + + def PrimaryExpression_Id(self): + if self.Peak == 'ID': + return self.parseDesignator() + self.Error('Expected ID, got {0}'.format(self.Peak)) + + def parse_type_spec(self): + """ Parse type specification """ if self.Peak == 'struct': self.Consume('struct') self.Consume('{') mems = [] while self.Peak != '}': - mem_t = self.parseTypeSpec() + mem_t = self.parse_type_spec() for i in self.parseIdSequence(): mems.append(StructField(i.val, mem_t)) self.Consume(';') @@ -122,15 +137,27 @@ # TODO) raise NotImplementedError() else: - theT = self.PostFixExpression() - # Check for pointer suffix: - while self.hasConsumed('*'): - theT = PointerType(theT) + theT = self.PostFixId() + + # Check for pointer or array suffix: + while self.Peak in ['*', '[']: + if self.hasConsumed('*'): + theT = PointerType(theT) + elif self.hasConsumed('['): + if self.Peak == ']': + size = 0 + self.Consume(']') + else: + size = self.Expression() + self.Consume(']') + theT = ArrayType(theT, size) + else: + raise Exception() return theT def parseTypeDef(self): self.Consume('type') - newtype = self.parseTypeSpec() + newtype = self.parse_type_spec() typename = self.Consume('ID') self.Consume(';') df = DefinedType(typename.val, newtype, typename.loc) @@ -139,7 +166,7 @@ # Variable declarations: def parseVarDef(self): self.Consume('var') - t = self.parseTypeSpec() + t = self.parse_type_spec() for name in self.parseIdSequence(): v = Variable(name.val, t) v.loc = name.loc @@ -149,7 +176,7 @@ def parseConstDef(self): self.Consume('const') - t = self.parseTypeSpec() + t = self.parse_type_spec() while True: name = self.Consume('ID') self.Consume('=') @@ -163,7 +190,7 @@ def parseFunctionDef(self): loc = self.Consume('function').loc - returntype = self.parseTypeSpec() + returntype = self.parse_type_spec() fname = self.Consume('ID').val f = Function(fname, loc) self.addDeclaration(f) @@ -173,7 +200,7 @@ parameters = [] if not self.hasConsumed(')'): while True: - typ = self.parseTypeSpec() + typ = self.parse_type_spec() name = self.Consume('ID') param = FormalParameter(name.val, typ) param.loc = name.loc @@ -187,7 +214,7 @@ f.body = self.parseCompound() self.currentPart = savePart - def parseIf(self): + def parse_if(self): loc = self.Consume('if').loc self.Consume('(') condition = self.Expression() @@ -204,7 +231,7 @@ statements = self.Statement() return While(condition, statements, loc) - def parseFor(self): + def parse_for(self): loc = self.Consume('for').loc self.Consume('(') init = self.Statement() @@ -235,11 +262,11 @@ def Statement(self): # Determine statement type based on the pending token: if self.Peak == 'if': - return self.parseIf() + return self.parse_if() elif self.Peak == 'while': return self.parseWhile() elif self.Peak == 'for': - return self.parseFor() + return self.parse_for() elif self.Peak == '{': return self.parseCompound() elif self.hasConsumed(';'): @@ -339,7 +366,7 @@ if self.Peak == 'cast': loc = self.Consume('cast').loc self.Consume('<') - t = self.parseTypeSpec() + t = self.parse_type_spec() self.Consume('>') self.Consume('(') ce = self.Expression() @@ -363,7 +390,9 @@ pfe = self.PrimaryExpression() while self.Peak in ['[', '.', '->', '(', '++']: if self.hasConsumed('['): - raise NotImplementedError('Array not yet implemented') + i = self.Expression() + self.Consume(']') + pfe = Index(pfe, i, i.loc) elif self.hasConsumed('->'): field = self.Consume('ID') pfe = Deref(pfe, pfe.loc) @@ -410,3 +439,4 @@ elif self.Peak == 'ID': return self.parseDesignator() self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak)) +
--- a/python/ppci/c3/scope.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/c3/scope.py Thu Mar 13 18:59:06 2014 +0100 @@ -1,4 +1,6 @@ from .astnodes import Constant, Variable, Function, BaseType, Symbol +from .astnodes import ArrayType, StructureType, DefinedType, PointerType +from .astnodes import StructField class Scope: @@ -72,6 +74,13 @@ scope.addSymbol(BaseType('double')) scope.addSymbol(BaseType('void')) scope.addSymbol(BaseType('bool')) - scope.addSymbol(BaseType('string')) - scope.addSymbol(BaseType('byte')) + byteType = BaseType('byte') + byteType.bytesize = target.byte_sizes['byte'] + scope.addSymbol(byteType) + + # Construct string type from others: + ln = StructField('len', intType) + txt = StructField('txt', ArrayType(byteType, 0)) + strType = DefinedType('string', PointerType(StructureType([ln, txt])), None) + scope.addSymbol(strType) return scope
--- a/python/ppci/c3/visitor.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/c3/visitor.py Thu Mar 13 18:59:06 2014 +0100 @@ -61,6 +61,9 @@ self.do(node.to_type) elif type(node) is Member: self.do(node.base) + elif type(node) is Index: + self.do(node.base) + self.do(node.i) elif type(node) is Deref: self.do(node.ptr) elif type(node) is Constant: @@ -75,6 +78,9 @@ elif type(node) is StructureType: for m in node.mems: self.do(m.typ) + elif type(node) is ArrayType: + self.do(node.element_type) + self.do(node.size) elif type(node) is FunctionType: for pt in node.parametertypes: self.do(pt)
--- a/python/ppci/codegen/canon.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/codegen/canon.py Thu Mar 13 18:59:06 2014 +0100 @@ -64,13 +64,16 @@ elif isinstance(exp, ir.Mem): exp.e = rewriteExp(exp.e, frame) return exp + elif isinstance(exp, ir.Addr): + exp.e = rewriteExp(exp.e, frame) + return exp elif isinstance(exp, ir.Call): exp.arguments = [rewriteExp(p, frame) for p in exp.arguments] # Rewrite call into eseq: t = newTemp() return ir.Eseq(ir.Move(t, exp), t) else: - raise NotImplementedError('NI: {}'.format(exp)) + raise NotImplementedError('NI: {}, {}'.format(exp, type(exp))) # The flatten functions pull out seq instructions to the sequence list. @@ -86,6 +89,9 @@ elif isinstance(exp, ir.Mem): exp.e, s = flattenExp(exp.e) return exp, s + elif isinstance(exp, ir.Addr): + exp.e, s = flattenExp(exp.e) + return exp, s elif isinstance(exp, ir.Eseq): s = flattenStmt(exp.stmt) exp.e, se = flattenExp(exp.e)
--- a/python/ppci/ir.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/ir.py Thu Mar 13 18:59:06 2014 +0100 @@ -214,7 +214,7 @@ self.arguments = arguments def __repr__(self): - args = ', '.join([str(arg) for arg in self.arguments]) + args = ', '.join(str(arg) for arg in self.arguments) return '{}({})'.format(self.f, args) @@ -309,6 +309,15 @@ return '[{}]'.format(self.e) +class Addr(Expression): + """ Address of label """ + def __init__(self, e): + self.e = e + + def __repr__(self): + return '&{}'.format(self.e) + + class Statement: """ Base class for all instructions. """ @property
--- a/python/ppci/ir2tree.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/ir2tree.py Thu Mar 13 18:59:06 2014 +0100 @@ -27,14 +27,26 @@ @register(ir.Const) def const_to_tree(e): - t = Tree('CONSTI32') - t.value = e.value - return t + if type(e.value) is bytes: + t = Tree('CONSTDATA') + t.value = e.value + print(t.value) + return t + elif type(e.value) is int: + t = Tree('CONSTI32') + t.value = e.value + return t + else: + raise Exception('{} not implemented'.format(type(e.value))) @register(ir.Mem) def mem_to_tree(e): return Tree('MEMI32', makeTree(e.e)) +@register(ir.Addr) +def mem_to_tree(e): + return Tree('ADR', makeTree(e.e)) + @register(ir.Call) def call_to_tree(e): t = Tree('CALL')
--- a/python/ppci/linker.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/linker.py Thu Mar 13 18:59:06 2014 +0100 @@ -103,6 +103,21 @@ section.data[reloc.offset+1] |= (offset >> 8) & 0xF section.data[reloc.offset+0] = offset & 0xFF +@reloc('adr_imm12') +def apply_adr_imm12(reloc, sym, section, reloc_value): + assert sym.value % 4 == 0 + assert reloc_value % 4 == 0 + offset = (sym.value - (reloc_value + 8)) + U = 2 + if offset < 0: + offset = -offset + U = 1 + assert offset < 4096 + section.data[reloc.offset+2] |= (U << 6) #(rel24 >> 16) & 0xFF + section.data[reloc.offset+1] |= (offset >> 8) & 0xF + section.data[reloc.offset+0] = offset & 0xFF + + class Linker: """ Merges the sections of several object files and performs relocation """
--- a/python/ppci/target/arm/__init__.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/target/arm/__init__.py Thu Mar 13 18:59:06 2014 +0100 @@ -4,9 +4,9 @@ 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 +from .instructions import Dcd, Mov, Add, Sub, Orr1, Mul, Mov2, Add1, Mul1 from .instructions import B, Bl, Ble, Bgt, Beq, Blt, Cmp, Cmp2 -from .instructions import Push, Pop, Str, Ldr, Ldr3, Str1, Ldr1 +from .instructions import Push, Pop, Str, Ldr, Ldr3, Str1, Ldr1, Adr from .selector import ArmInstructionSelector from .frame import ArmFrame @@ -20,9 +20,11 @@ self.add_lowering(Ldr3, lambda im: Ldr3(im.dst[0], im.others[0])) self.add_lowering(Str1, lambda im: Str1(im.src[1], im.src[0], im.others[0])) self.add_lowering(Ldr1, lambda im: Ldr1(im.dst[0], im.src[0], im.others[0])) + self.add_lowering(Adr, lambda im: Adr(im.dst[0], im.others[0])) self.add_lowering(Mov2, lambda im: Mov2(im.dst[0], im.src[0])) self.add_lowering(Cmp2, lambda im: Cmp2(im.src[0], im.src[1])) self.add_lowering(Add1, lambda im: Add1(im.dst[0], im.src[0], im.src[1])) + self.add_lowering(Mul1, lambda im: Mul1(im.dst[0], im.src[0], im.src[1])) def make_parser(self): # Assembly grammar: @@ -134,6 +136,10 @@ self.add_instruction(['str', 'reg', ',', '[', 'reg', ',', 'reg', ']'], lambda rhs: Str(rhs[1], rhs[4], rhs[6])) + self.add_keyword('adr') + self.add_instruction(['adr', 'reg', ',', 'ID'], + lambda rhs: Adr(rhs[1], rhs[3].val)) + # Register list grammar: self.add_rule('reg_list', ['{', 'reg_list_inner', '}'], lambda rhs: rhs[1])
--- a/python/ppci/target/arm/arm.brg Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/target/arm/arm.brg Thu Mar 13 18:59:06 2014 +0100 @@ -1,18 +1,20 @@ -from ppci.target.arm.instructions import Add1, Sub1, Ldr1, Ldr3 +from ppci.target.arm.instructions import Add1, Sub1, Mul1 +from ppci.target.arm.instructions import Ldr1, Ldr3, Adr %% -%terminal ADDI32 SUBI32 MULI32 +%terminal ADDI32 SUBI32 MULI32 ADR %terminal ORI32 SHLI32 -%terminal CONSTI32 MEMI32 REGI32 CALL +%terminal CONSTI32 CONSTDATA MEMI32 REGI32 CALL %terminal MOVI32 %% 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: 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: 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 .) @@ -20,6 +22,9 @@ cn: CONSTI32 0 (. return $$.value .) reg: CONSTI32 3 (. d = self.newTmp(); ln = self.selector.frame.add_constant($$.value); self.emit(Ldr3, dst=[d], others=[ln]); 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: REGI32 1 (. return $$.value .) reg: CALL 1 (. return self.selector.munchCall($$.value) .)
--- a/python/ppci/target/arm/frame.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/target/arm/frame.py Thu Mar 13 18:59:06 2014 +0100 @@ -52,6 +52,7 @@ return self.locVars[lvar] def add_constant(self, value): + assert type(value) in [int, bytes] lab_name = '{}_literal_{}'.format(self.name, len(self.constants)) self.constants.append((lab_name, value)) return lab_name @@ -83,13 +84,13 @@ for ln, v in self.constants: if isinstance(v, int): post.extend([Label(ln), Dcd(v)]) - elif isinstance(v, str): - post.extend([Label(ln), Dcd(len(v))]) + elif isinstance(v, bytes): + post.append(Label(ln)) for c in v: - post.append(Db(ord(c))) + post.append(Db(c)) post.append(Alignment(4)) # Align at 4 bytes else: - raise Exception() + raise Exception('Constant of type {} not supported'.format(v)) return post def EntryExitGlue3(self):
--- a/python/ppci/target/arm/instructions.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/target/arm/instructions.py Thu Mar 13 18:59:06 2014 +0100 @@ -173,7 +173,7 @@ return Mul1(args[0], args[1], args[2]) -class Mul(ArmInstruction): +class Mul1(ArmInstruction): def __init__(self, rd, rn, rm): super().__init__() self.rd = rd @@ -211,18 +211,21 @@ return self.token.encode() def __repr__(self): - return 'add {}, {}, {}'.format(self.rd, self.rn, self.rm) + return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.rm) class Add1(OpRegRegReg): + mnemonic = 'ADD' opcode = 0b0000100 class Sub1(OpRegRegReg): + mnemonic = 'SUB' opcode = 0b0000010 class Orr1(OpRegRegReg): + mnemonic = 'ORR' opcode = 0b0001100 @@ -245,14 +248,16 @@ return self.token.encode() def __repr__(self): - return 'add {}, {}, {}'.format(self.rd, self.rn, self.imm) + return '{} {}, {}, {}'.format(self.mnemonic, self.rd, self.rn, self.imm) class Add2(OpRegRegImm): + mnemonic = 'ADD' opcode = 0b0010100 class Sub2(OpRegRegImm): + mnemonic = 'SUB' opcode = 0b0010010 @@ -393,6 +398,7 @@ return '{} {}, [{}, {}]'.format(self.mnemonic, self.rt, self.rn, hex(self.offset)) + class Str1(LdrStrBase): opcode = 0b010 bit20 = 0 @@ -405,6 +411,27 @@ mnemonic = 'LDR' +class Adr(ArmInstruction): + def __init__(self, rd, label): + super().__init__() + self.rd = rd + self.label = label + + def __repr__(self): + return 'ADR {}, {}'.format(self.rd, self.label) + + def relocations(self): + return [(self.label, 'adr_imm12')] + + def encode(self): + self.token.cond = AL + self.token[0:12] = 0 # Filled by linker + self.token[12:16] = self.rd.num + self.token[16:20] = 0b1111 + self.token[25] = 1 + return self.token.encode() + + class Ldr3(ArmInstruction): """ Load PC relative constant value LDR rt, label
--- a/python/ppci/target/basetarget.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/ppci/target/basetarget.py Thu Mar 13 18:59:06 2014 +0100 @@ -21,6 +21,9 @@ def encode(self): return bytes() + def __repr__(self): + return 'NOP' + class PseudoInstruction(Instruction): pass @@ -84,6 +87,7 @@ self.desc = desc self.registers = [] self.byte_sizes = {'int' : 4} # For front end! + self.byte_sizes['byte'] = 1 # For lowering: self.lower_functions = {}
--- a/python/pyburg.py Sun Mar 09 18:49:10 2014 +0100 +++ b/python/pyburg.py Thu Mar 13 18:59:06 2014 +0100 @@ -252,11 +252,12 @@ # TODO: check for rules fullfilled (by not using 999999) self.print(' nts = self.nts({})'.format(rule.nr)) self.print(' kids = self.kids(tree, {})'.format(rule.nr)) - 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)) + self.print(' if all(x.state.has_goal(y) for x, y in zip(kids, nts)):') + 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: - self.print(' # Chain rule: {}'.format(cr)) - self.print(' tree.state.set_cost("{}", c + {}, {})'.format(cr.non_term, cr.cost, cr.nr)) + self.print(' # Chain rule: {}'.format(cr)) + self.print(' tree.state.set_cost("{}", c + {}, {})'.format(cr.non_term, cr.cost, cr.nr)) def emit_state(self): """ Emit a function that assigns a new state to a node """
--- a/test/testarmasm.py Sun Mar 09 18:49:10 2014 +0100 +++ b/test/testarmasm.py Thu Mar 13 18:59:06 2014 +0100 @@ -95,6 +95,16 @@ self.feed('mul r4,r5,r2') self.check('174045e2 ffffffba 950204e0') + def testAdr(self): + self.feed('adr r5, cval') + self.feed('adr r9, cval') + self.feed('adr r8, cval') + self.feed('cval:') + self.feed('adr r11, cval') + self.feed('adr r12, cval') + self.feed('adr r1, cval') + self.check('04508fe2 00908fe2 04804fe2 08b04fe2 0cc04fe2 10104fe2') + if __name__ == '__main__': unittest.main()
--- a/test/testc3.py Sun Mar 09 18:49:10 2014 +0100 +++ b/test/testc3.py Thu Mar 13 18:59:06 2014 +0100 @@ -343,6 +343,45 @@ """ self.expectErrors(snippet, [5]) + def testArray(self): + snippet = """ + module testarray; + function void t() + { + var int[100] x; + var int a, b; + a = 2; + b = x[a*2+9 - a] * x[22+12]; + x[1] = x[2]; + } + """ + self.expectOK(snippet) + + def testArrayFail(self): + snippet = """ + module testarray; + function void t() + { + var bool c; + c = false; + var int[100] x; + x[1] = x[c]; + } + """ + self.expectErrors(snippet, [8]) + + def testArrayFail2(self): + snippet = """ + module testarray; + function void t() + { + var int c; + var int x; + c = x[2]; + } + """ + self.expectErrors(snippet, [7]) + def testStructCall(self): snippet = """ module teststruct1;
--- a/test/testemulation.py Sun Mar 09 18:49:10 2014 +0100 +++ b/test/testemulation.py Thu Mar 13 18:59:06 2014 +0100 @@ -80,7 +80,7 @@ recipe = os.path.join(testdir, '..', 'kernel', 'arm.yaml') self.buildRecipe(recipe) data = self.runQemu('../kernel/kernel_arm.bin', machine='vexpress-a9') - self.assertEqual('e', data[0]) + self.assertEqual('Welcome to lcfos!', data) if __name__ == '__main__':