# HG changeset patch # User Windel Bouwman # Date 1373795458 -7200 # Node ID e621e3ba78d251e8bb262de52f0a1b9d940b85df # Parent 521567d173889dcb30b41f0866894fd480e3284e Added left shift instruction diff -r 521567d17388 -r e621e3ba78d2 python/c3/codegenerator.py --- a/python/c3/codegenerator.py Sat Jul 13 20:20:44 2013 +0200 +++ b/python/c3/codegenerator.py Sun Jul 14 11:50:58 2013 +0200 @@ -4,7 +4,8 @@ from ppci import CompilerError from .typecheck import theType -tmpnames = {'+':'add', '-':'sub', '*': 'mul', '/':'div', '|':'or', '&':'and'} +tmpnames = {'+':'add', '-':'sub', '*': 'mul', '/':'div', '|':'or', \ + '&':'and', '>>':'shl', '<<':'shr'} class CodeGenerator: """ Generates intermediate code from a package """ @@ -141,7 +142,7 @@ if type(expr) is astnodes.Binop: ra = self.genExprCode(expr.a) rb = self.genExprCode(expr.b) - ops = ['+', '-', '*', '/', '|', '&'] + ops = ['+', '-', '*', '/', '|', '&', '<<', '>>'] if expr.op in ops: tmp = self.builder.newTmp(tmpnames[expr.op]) op = expr.op diff -r 521567d17388 -r e621e3ba78d2 python/c3/lexer.py --- a/python/c3/lexer.py Sat Jul 13 20:20:44 2013 +0200 +++ b/python/c3/lexer.py Sun Jul 14 11:50:58 2013 +0200 @@ -29,7 +29,7 @@ ('COMMENTS', r'//.*'), ('LONGCOMMENTBEGIN', r'\/\*'), ('LONGCOMMENTEND', r'\*\/'), - ('LEESTEKEN', r'==|->|[\.,=:;\-+*\[\]/\(\)]|>=|<=|<>|>|<|{|}|&|\^|\|'), + ('LEESTEKEN', r'==|->|<<|>>|[\.,=:;\-+*\[\]/\(\)]|>=|<=|<>|>|<|{|}|&|\^|\|'), ('STRING', r"'.*?'") ] tok_re = '|'.join('(?P<%s>%s)' % pair for pair in tok_spec) diff -r 521567d17388 -r e621e3ba78d2 python/c3/parser.py --- a/python/c3/parser.py Sat Jul 13 20:20:44 2013 +0200 +++ b/python/c3/parser.py Sun Jul 14 11:50:58 2013 +0200 @@ -270,6 +270,15 @@ return ee def SimpleExpression(self): + """ Shift operations before + and - ? """ + e = self.AddExpression() + while self.Peak in ['>>', '<<']: + op = self.Consume(self.Peak) + e2 = self.AddExpression() + e = astnodes.Binop(e, op.typ, e2, op.loc) + return e + + def AddExpression(self): e = self.Term() while self.Peak in ['+', '-']: op = self.Consume(self.Peak) @@ -314,7 +323,7 @@ t = self.parseTypeSpec() self.Consume('>') self.Consume('(') - ce = self.CastExpression() + ce = self.Expression() self.Consume(')') return astnodes.TypeCast(t, ce, loc) else: diff -r 521567d17388 -r e621e3ba78d2 python/c3/typecheck.py --- a/python/c3/typecheck.py Sat Jul 13 20:20:44 2013 +0200 +++ b/python/c3/typecheck.py Sun Jul 14 11:50:58 2013 +0200 @@ -145,7 +145,7 @@ sym.typ = intType elif type(sym) is Binop: sym.lvalue = False - if sym.op in ['+', '-', '*', '/']: + if sym.op in ['+', '-', '*', '/', '<<', '>>', '|', '&']: expectRval(sym.a) expectRval(sym.b) if equalTypes(sym.a.typ, sym.b.typ): @@ -168,14 +168,6 @@ self.error('Must be {0}'.format(boolType), sym.a.loc) if not equalTypes(sym.b.typ, boolType): self.error('Must be {0}'.format(boolType), sym.b.loc) - elif sym.op in ['|', '&']: - sym.typ = intType - sym.lvalue = False - if equalTypes(sym.a.typ, sym.b.typ): - if not equalTypes(sym.a.typ, intType): - self.error('Can only add integers', sym.loc) - else: - self.error('Types unequal {} != {}'.format(sym.a.typ, sym.b.typ), sym.loc) else: raise Exception('Unknown binop {0}'.format(sym.op)) elif type(sym) is Variable: diff -r 521567d17388 -r e621e3ba78d2 python/codegenarm.py --- a/python/codegenarm.py Sat Jul 13 20:20:44 2013 +0200 +++ b/python/codegenarm.py Sun Jul 14 11:50:58 2013 +0200 @@ -26,6 +26,11 @@ self.imms = [] # list with immediates relative to PC. self.outs.selectSection('code') + + # Manually inserted startup code: + self.emit(arm.dcd_ins(0x20000678)) # initial stack ptr + self.emit(arm.dcd_ins(0x08000401)) # reset vector + for f in ircode.Functions: # Add global variable addresses to immediate list: for gvar in ircode.Variables: @@ -63,45 +68,48 @@ self.emit(AComment(txt)) def generateInstruction(self, ins): + self.comment(str(ins)) if type(ins) is ir.Branch: tgt = ALabel(ins.target.name) self.emit(arm.jmp_ins(tgt)) elif type(ins) is ir.ImmLoad: - self.comment(str(ins)) lname = ins.target.name + '_ivalue' self.emit(arm.ldr_pcrel(arm.r0, ALabel(lname))) self.imms.append((lname, ins.value)) self.emit(arm.str_sprel(arm.r0, arm.MemSpRel(self.addStack(ins.target)))) elif type(ins) is ir.Store: - self.comment(str(ins)) # Load value in r0: self.loadStack(arm.r0, ins.value) # store in memory: - self.getGlobal(arm.r1, ins.location) + # TODO: split globals and locals?? + #self.getGlobal(arm.r1, ins.location) + self.loadStack(arm.r1, ins.location) self.emit(arm.storeimm5_ins(arm.r0, arm.MemR8Rel(arm.r1, 0))) elif type(ins) is ir.Load: - self.comment(str(ins)) - self.getGlobal(arm.r0, ins.location) + # TODO: differ global and local?? + #self.getGlobal(arm.r0, ins.location) + self.loadStack(arm.r0, ins.location) self.emit(arm.loadimm5_ins(arm.r0, arm.MemR8Rel(arm.r0, 0))) # Store value on stack: self.emit(arm.str_sprel(arm.r0, arm.MemSpRel(self.addStack(ins.value)))) elif type(ins) is ir.BinaryOperator: - self.comment(str(ins)) # Load operands: self.loadStack(arm.r0, ins.value1) self.loadStack(arm.r1, ins.value2) # do operation: if ins.operation == '+': self.emit(arm.addregs_ins(arm.r0, arm.r0, arm.r1)) + elif ins.operation == '<<': + self.emit(arm.lslregs_ins(arm.r0, arm.r1)) + elif ins.operation == '|': + self.emit(arm.orrregs_ins(arm.r0, arm.r1)) else: print('operation not implemented', ins.operation) # Store value back: self.emit(arm.str_sprel(arm.r0, arm.MemSpRel(self.addStack(ins.result)))) elif type(ins) is ir.Return: - self.comment(str(ins)) self.emit(arm.pop_ins(arm.RegisterSet({arm.r4, arm.r5, arm.r6, arm.r7, arm.pc}))) elif type(ins) is ir.ConditionalBranch: - self.comment(str(ins)) self.loadStack(arm.r0, ins.a) self.loadStack(arm.r1, ins.b) self.emit(arm.cmp_ins(arm.r1, arm.r0)) @@ -113,6 +121,7 @@ tgt_no = ALabel(ins.lab2.name) self.emit(arm.jmp_ins(tgt_no)) elif type(ins) is ir.Alloc: + # Local variables are added to stack self.addStack(ins.value) else: raise CompilerError('IR "{}" not covered'.format(ins)) diff -r 521567d17388 -r e621e3ba78d2 python/cortexm3.py --- a/python/cortexm3.py Sat Jul 13 20:20:44 2013 +0200 +++ b/python/cortexm3.py Sun Jul 14 11:50:58 2013 +0200 @@ -278,7 +278,7 @@ return u16(h) def __repr__(self): - return 'LDR {}, [pc,#{}]'.format(self.rt, self.offset) + return 'LDR {}, {}'.format(self.rt, self.label.name) @armtarget.instruction class ldr_sprel(ls_sp_base_imm8): @@ -311,7 +311,8 @@ return u16(h) def __repr__(self): return 'MOV {0}, xx?'.format(self.r) - + + @armtarget.instruction class movregreg_ins(ArmInstruction): """ mov Rd, Rm """ @@ -410,6 +411,11 @@ opcode = 0b0100001010 @armtarget.instruction +class lslregs_ins(regreg_base): + mnemonic = 'LSL' + opcode = 0b0100000010 + +@armtarget.instruction class cmpregimm8_ins(ArmInstruction): """ cmp Rn, imm8 """ mnemonic = 'cmp' diff -r 521567d17388 -r e621e3ba78d2 python/stm32f4/blink.c3 --- a/python/stm32f4/blink.c3 Sat Jul 13 20:20:44 2013 +0200 +++ b/python/stm32f4/blink.c3 Sun Jul 14 11:50:58 2013 +0200 @@ -1,4 +1,9 @@ -// This file blinks a LED on the STM32F4 discovery board. +/* This file blinks a LED on the STM32F4 discovery board. + +the board has 4 leds on PD12, PD13, PD14 and PD15 + +*/ + package blink; type struct { @@ -11,36 +16,42 @@ }* GPIO_Type; type struct { -} RCC_Type; + int CR; + int PLLCFGR; + int CFGR; + int CIR; + int AHB1RSTR; + int AHB2RSTR; + int AHB3RSTR; + int reserved0; + int APB1RSTR; + int APB2RSTR; + int reserved1a, reserved1b; + int AHB1ENR; + int AHB2ENR; + int AHB3ENR; + int reserved2; + int APB1ENR, APB2ENR; +}* RCC_Type; // Functions: function void main() { - var int APB1PERIPH_BASE; - APB1PERIPH_BASE = 0x40000000 - //var int + // Memory mapped control registers: var GPIO_Type GPIOD; - GPIOD = cast(0x400000); + GPIOD = cast(0x40020C00); + var RCC_Type RCC; + RCC = cast(0x40023800); - var int* RCC_AHB1ENR; - RCC_AHB1ENR = cast(0x40003022); - *RCC_AHB1ENR = *RCC_AHB1ENR | 8943; - /* - RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; - RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; - - GPIOD->MODER = (1<<26); - - NVIC->ISER[0] |= 1<< (TIM2_IRQn); - - TIM2->PSC = 0xE000; - TIM2->DIER |= TIM_DIER_UIE; - TIM2->ARR = 0xE000; - TIM2->CR1 |= TIM_CR1_ARPE | TIM_CR1_CEN; - TIM2->EGR = 1; - - */ + // Enable the clock to port D: + RCC->AHB1ENR = RCC->AHB1ENR | 0x8; + + + // PD13 == output (01) + GPIOD->MODER = (1 << 26); + GPIOD->ODR = (1 << 13); + while(true) {} } diff -r 521567d17388 -r e621e3ba78d2 python/testasm.py --- a/python/testasm.py Sat Jul 13 20:20:44 2013 +0200 +++ b/python/testasm.py Sun Jul 14 11:50:58 2013 +0200 @@ -158,7 +158,7 @@ def check(self, hexstr): self.assertSequenceEqual(bytes.fromhex(hexstr), self.a.binout) - + def testMapOperand(self): pass @@ -198,6 +198,10 @@ self.feed('cmp r0, r1') self.check('8842') + def testLeftShit(self): + self.feed('lsl r3, r5') + self.check('ab40') + def testSequence1(self): self.feed('mov r5, 3') self.feed('add r4, r5, 0')