Mercurial > lcfOS
changeset 237:81752b0f85a5
Added burn led test program
author | Windel Bouwman |
---|---|
date | Wed, 17 Jul 2013 22:31:54 +0200 |
parents | 8786811a5a59 |
children | 90637d1bbfad |
files | python/c3/examples/types.c3 python/codegenarm.py python/cortexm3.py python/outstream.py python/stm32f4/burn.c3 python/testasm.py python/testir.py python/testzcc.py python/transform.py python/zcc.py |
diffstat | 10 files changed, 277 insertions(+), 65 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/c3/examples/types.c3 Wed Jul 17 22:31:54 2013 +0200 @@ -0,0 +1,40 @@ + +/* + Demo of how to define types +*/ + +package typedemo; + +type int A; +type int B; +type struct { + int x, y; + A z; +} C; +type struct { + C x; + B y; + int z; +} D; + +type D* E; + +function int testcast() +{ + var A a; + var B b; + a = 3; + b = a; + var C c; + c.x = a; + c.z = c.y; + var D d; + var E e; + var D* e2; + e = &d; + e2 = e; + e2->x.x = 22; + + return 0; +} +
--- a/python/codegenarm.py Mon Jul 15 20:15:31 2013 +0200 +++ b/python/codegenarm.py Wed Jul 17 22:31:54 2013 +0200 @@ -28,8 +28,11 @@ # Manually inserted startup code: self.dcd(0x20000678) # initial stack ptr - self.dcd(0x08000401) # reset vector + # TODO: use label here: + #self.emit(arm.dcd_ins(LabelRef('reset'))) # reset vector + self.dcd(0x08000009) # reset vector, lsb indicates thumb mode + self.emit(Label('reset')) for f in ircode.Functions: # Add global variable addresses to immediate list: for gvar in ircode.Variables: @@ -50,6 +53,8 @@ self.emit(Label(l)) self.dcd(v) self.align() + self.outs.backpatch() + self.outs.backpatch() def dcd(self, x): self.emit(arm.dcd_ins(Imm32(x))) @@ -74,8 +79,8 @@ def generateInstruction(self, ins): self.comment(str(ins)) if type(ins) is ir.Branch: - tgt = Label(ins.target.name) - self.emit(arm.jmp_ins(tgt)) + tgt = LabelRef(ins.target.name) + self.emit(arm.b_ins(tgt)) elif type(ins) is ir.ImmLoad: lname = ins.target.name + '_ivalue' self.emit(arm.ldr_pcrel(arm.r0, LabelRef(lname))) @@ -108,7 +113,7 @@ elif ins.operation == '|': self.emit(arm.orrregs_ins(arm.r0, arm.r1)) else: - print('operation not implemented', ins.operation) + raise NotImplementedError('operation {} not implemented'.format(ins.operation)) # Store value back: self.emit(arm.str_sprel(arm.r0, arm.MemSpRel(self.addStack(ins.result)))) elif type(ins) is ir.Return: @@ -121,13 +126,13 @@ if ins.cond == '==': self.emit(arm.beq_ins(tgt_yes)) else: - print('TODO', ins.cond) + raise NotImplementedError('"{}" not covered'.format(ins.cond)) tgt_no = Label(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)) + raise NotImplementedError('IR "{}" not covered'.format(ins))
--- a/python/cortexm3.py Mon Jul 15 20:15:31 2013 +0200 +++ b/python/cortexm3.py Wed Jul 17 22:31:54 2013 +0200 @@ -201,8 +201,18 @@ mnemonic = 'dcd' operands = (Imm32,) def __init__(self, expr): - assert isinstance(expr, Imm32) - self.expr = expr.imm + if isinstance(expr, Imm32): + self.expr = expr.imm + self.label = None + elif isinstance(expr, LabelRef): + self.expr = 0 + self.label = expr + else: + raise NotImplementedError() + + def resolve(self, f): + if self.label: + self.expr = f(self.label.name) def encode(self): return u32(self.expr) @@ -451,35 +461,48 @@ # Jumping: -@armtarget.instruction -class jmp_ins(ArmInstruction): - operands = (Label,) - mnemonic = 'jmp' +class jumpBase_ins(ArmInstruction): + operands = (LabelRef,) def __init__(self, target_label): - assert type(target_label) is Label + assert type(target_label) is LabelRef self.target = target_label - def fixUp(self): - pass - def encode(self): - h = 0 # TODO - return u16(h) + self.offset = 0 + + def resolve(self, f): + la = f(self.target.name) + sa = self.address + self.offset = (la - sa) + if self.offset < 0: + # TODO: handle negative jump + self.offset = 0 + def __repr__(self): - return 'B {0}'.format(self.target.name) + return '{} {}'.format(self.mnemonic, self.target.name) @armtarget.instruction -class beq_ins(ArmInstruction): - operands = (Label,) +class b_ins(jumpBase_ins): + mnemonic = 'B' + + def encode(self): + imm11 = self.offset >> 1 + h = (0b11100 << 11) | imm11 | 1 # 1 to enable thumb mode + return u16(h) + +class cond_base_ins(jumpBase_ins): + def encode(self): + imm8 = 0 + h = (0b1101 << 12) | (self.cond << 8) | imm8 + return u16(h) + +@armtarget.instruction +class beq_ins(cond_base_ins): mnemonic = 'beq' - def __init__(self, target_label): - assert type(target_label) is Label - self.target = target_label - def fixUp(self): - pass - def encode(self): - h = 0 # TODO - return u16(h) - def __repr__(self): - return 'BEQ {0}'.format(self.target.name) + cond = 0 + +@armtarget.instruction +class beq_ins(cond_base_ins): + mnemonic = 'bne' + cond = 1 @armtarget.instruction class push_ins(ArmInstruction):
--- a/python/outstream.py Mon Jul 15 20:15:31 2013 +0200 +++ b/python/outstream.py Wed Jul 17 22:31:54 2013 +0200 @@ -7,24 +7,41 @@ """ +class Section: + def __init__(self): + self.instructions = [] + + def emit(self, item): + assert isinstance(item, Instruction) + self.instructions.append(item) + + def to_bytes(self): + d = bytearray() + for i in self.instructions: + addr = i.address + insword = i.encode() + assert type(insword) is bytes + d.extend(insword) + return bytes(d) + class OutputStream: def __init__(self): self.sections = {} self.currentSection = None def emit(self, item): - assert isinstance(item, Instruction) - self.sections[self.currentSection].append(item) + assert self.currentSection + self.sections[self.currentSection].emit(item) def selectSection(self, s): self.currentSection = s if not s in self.sections: - self.sections[s] = [] + self.sections[s] = Section() def getLabelAddress(self, lname): assert isinstance(lname, str) for s in self.sections.values(): - for i in s: + for i in s.instructions: if type(i) is Label: if i.name == lname: return i.address @@ -40,7 +57,8 @@ address = 0x02000000 else: address = 0x0 - for i in self.sections[s]: + + for i in self.sections[s].instructions: i.address = address i.resolve(self.getLabelAddress) bts = i.encode() @@ -53,8 +71,8 @@ self.dumpSection(s) def dumpSection(self, s): - print('.section '+s) - for i in self.sections[s]: + print('.section '+ s) + for i in self.sections[s].instructions: addr = i.address insword = i.encode() assert type(insword) is bytes @@ -69,8 +87,6 @@ pass class BinOutputStream(OutputStream): - def dump(self): - pass @property def Data(self): @@ -80,15 +96,7 @@ def dump(self): self.backpatch() self.backpatch() - section = list(self.sections.keys())[0] - return self.dumpSection(section) + section = self.sections[list(self.sections.keys())[0]] + return section.to_bytes() - def dumpSection(self, s): - d = bytearray() - for i in self.sections[s]: - addr = i.address - insword = i.encode() - assert type(insword) is bytes - d.extend(insword) - return d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/stm32f4/burn.c3 Wed Jul 17 22:31:54 2013 +0200 @@ -0,0 +1,60 @@ +/* + +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 { + int MODER; + int OTYPER; + int OSPEEDR; + int PUPDR; + int IDR; + int ODR; +}* GPIO_Type; + +type struct { + 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() +{ + // Memory mapped control registers: + var GPIO_Type GPIOD; + GPIOD = cast<GPIO_Type>(0x40020C00); + var RCC_Type RCC; + RCC = cast<RCC_Type>(0x40023800); + + // Enable the clock to port D: + RCC->AHB1ENR = RCC->AHB1ENR | (1 << 3); + + var int pin; + pin = 13; + // PD13 == output (01) + GPIOD->MODER = (1 << (pin << 1)); + GPIOD->ODR = (1 << pin); + + while(true) {} +} +
--- a/python/testasm.py Mon Jul 15 20:15:31 2013 +0200 +++ b/python/testasm.py Wed Jul 17 22:31:54 2013 +0200 @@ -212,11 +212,36 @@ self.check('0190') def testLdrPcRel(self): + self.feed('ldr r7, henkie') + self.feed('ldr r6, henkie') self.feed('ldr r1, henkie') self.feed('align 4') self.feed('dcd 1') self.feed('henkie: dcd 2') - self.check('014900000100000002000000') + self.check('024F024E 01490000 01000000 02000000') + + def testBranch(self): + self.feed('start: b henkie') + self.feed('beq henkie') + self.feed('bne henkie') + self.feed('henkie: b start') + self.feed('eof: b eof') + self.check('01e000d0 ffd1fbe7 fee7') + + def testBoff(self): + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.feed('henkie:') + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.feed('b henkie') + self.check('05e004e0 03e002e0 01e000e0 ffe7fee7 fde7fce7 fbe7') def testCmpRegReg(self): self.feed('cmp r0, r1')
--- a/python/testir.py Mon Jul 15 20:15:31 2013 +0200 +++ b/python/testir.py Wed Jul 17 22:31:54 2013 +0200 @@ -5,10 +5,10 @@ def setUp(self): self.b = ir.Builder() self.cf = transform.ConstantFolder() + self.m = ir.Module('test') + self.b.setModule(self.m) def testBuilder(self): - m = ir.Module('test') - self.b.setModule(m) f = self.b.newFunction('test') self.b.setFunction(f) bb = self.b.newBB() @@ -19,11 +19,22 @@ self.b.addIns(ir.ImmLoad(v1, 5)) self.b.addIns(ir.ImmLoad(v2, 7)) self.b.addIns(ir.BinaryOperator(v3, '+', v1, v2)) - self.assertEqual(3, len(m.Instructions)) - self.cf.run(m) - self.assertEqual(3, len(m.Instructions)) - self.assertIsInstance(m.Instructions[-1], ir.ImmLoad) - self.assertEqual(12, m.Instructions[-1].value) + self.assertEqual(3, len(self.m.Instructions)) + self.cf.run(self.m) + self.assertEqual(3, len(self.m.Instructions)) + self.assertIsInstance(self.m.Instructions[-1], ir.ImmLoad) + self.assertEqual(12, self.m.Instructions[-1].value) + + def testAdd0(self): + f = self.b.newFunction('test') + self.b.setFunction(f) + bb = self.b.newBB() + self.b.setBB(bb) + v1 = self.b.newTmp('t') + v2 = self.b.newTmp('t') + v3 = self.b.newTmp('t') + self.b.addIns(ir.ImmLoad(v2, 0)) + self.b.addIns(ir.BinaryOperator(v3, '+', v1, v2)) testsrc = """ @@ -75,8 +86,8 @@ """ if __name__ == '__main__': - unittest.main() - sys.exit() + #unittest.main() + #sys.exit() diag = ppci.DiagnosticsManager() builder = c3.Builder(diag) cgenx86 = x86.X86CodeGenSimple(diag)
--- a/python/testzcc.py Mon Jul 15 20:15:31 2013 +0200 +++ b/python/testzcc.py Wed Jul 17 22:31:54 2013 +0200 @@ -1,15 +1,22 @@ import unittest +import glob import zcc class ZccTestCase(unittest.TestCase): """ Tests the compiler driver """ - def testBlinkDemo(self): + def do(self, fn): """ Compile blink.c3 """ #args = zcc.parser.parse_args(['-d', 'stm32f4/blink.c3']) - args = zcc.parser.parse_args(['stm32f4/blink.c3']) + args = zcc.parser.parse_args([fn]) zcc.main(args) + def testExamples(self): + """ Test all examples in the c3/examples directory """ + example_filenames = glob.glob('./stm32f4/*.c3') + for filename in example_filenames: + self.do(filename) + if __name__ == '__main__': unittest.main()
--- a/python/transform.py Mon Jul 15 20:15:31 2013 +0200 +++ b/python/transform.py Wed Jul 17 22:31:54 2013 +0200 @@ -54,6 +54,37 @@ i2 = ImmLoad(i.result, vr) i.Parent.replaceInstruction(i, i2) + +class ConstantMerge(InstructionPass): + def prepare(self): + self.constMap = {} + def onInstruction(self, i): + if type(i) is ImmLoad: + v = i.value + if v in self.constMap: + # v is already defined, re-use the imm-load from elsewhere + pass + else: + self.constMap[v] = i + elif type(i) is BinaryOperator: + if i.value1 in self.constMap and i.value2 in self.constMap: + op = i.operation + va = self.constMap[i.value1] + vb = self.constMap[i.value2] + if op == '+': + vr = va + vb + elif op == '*': + vr = va * vb + elif op == '-': + vr = va - vb + else: + vr = None + return + self.constMap[i.result] = vr + i2 = ImmLoad(i.result, vr) + i.Parent.replaceInstruction(i, i2) + + class DeadCodeDeleter(BasicBlockPass): def onBasicBlock(self, bb): def instructionUsed(ins):
--- a/python/zcc.py Mon Jul 15 20:15:31 2013 +0200 +++ b/python/zcc.py Wed Jul 17 22:31:54 2013 +0200 @@ -41,12 +41,14 @@ if args.dumpir: outs.dump() + code_bytes = outs.sections['code'].to_bytes() + print('bytes:', code_bytes) if args.output: output_filename = args.output else: - output_filename = 'lc.output' - - # TODO: store data + output_filename = 'b.output' + with open(output_filename, 'wb') as f: + f.write(code_bytes) if __name__ == '__main__': arguments = parser.parse_args()