# HG changeset patch # User Windel Bouwman # Date 1379361077 -7200 # Node ID 56d37ed4b4d27c9d814d36b7e94d6113caed6af8 # Parent 6f2423df0675b2b7601b9734d4f3fc2d33be6d09 phaa diff -r 6f2423df0675 -r 56d37ed4b4d2 python/codegenarm.py --- a/python/codegenarm.py Sat Sep 14 17:29:10 2013 +0200 +++ b/python/codegenarm.py Mon Sep 16 21:51:17 2013 +0200 @@ -35,6 +35,8 @@ self.tempMap[self.fp] = 'r7' self.locVars = {} self.parMap = {} + # Literal pool: + self.constants = [] def argLoc(self, pos): """ @@ -57,6 +59,11 @@ self.stacksize = self.stacksize + 4 return self.locVars[lvar] + def addConstant(self, value): + lab_name = '{}_literal_{}'.format(self.name, len(self.constants)) + self.constants.append((lab_name, value)) + return lab_name + def EntryExitGlue3(self): """ Add code for the prologue and the epilogue. Add a label, the @@ -68,9 +75,14 @@ self.instructions.insert(3, makeIns('add sp, sp, {}'.format(self.stacksize))) self.instructions.append(makeIns('sub sp, sp, {}'.format(self.stacksize))) self.instructions.append(makeIns('pop {pc,r7}')) + # Add constant literals: + for ln, v in self.constants: + self.instructions.append(makeIns('{}:'.format(ln))) + self.instructions.append(makeIns('dcd {}'.format(v))) class ArmInstructionSelector(InstructionSelector): + """ Instruction selector for the arm architecture """ def munchExpr(self, e): if isinstance(e, ir.Alloc): @@ -101,24 +113,32 @@ a = self.munchExpr(e.a) b = self.munchExpr(e.b) d = self.newTmp() - self.emit('or %d0, %s0, %s1', dst=[d], src=[a, b]) + self.emit('mov %d0, %s0', src=[a], dst=[d]) + self.emit('orr %d0, %s0', dst=[d], src=[b, d]) return d elif isinstance(e, ir.Binop) and e.operation == '<<': a = self.munchExpr(e.a) b = self.munchExpr(e.b) d = self.newTmp() - self.emit('lsl %d0, %s0, %s1', dst=[d], src=[a, b]) + self.emit('mov %d0, %s0', src=[a], dst=[d]) + self.emit('lsl %d0, %s0', dst=[d], src=[b, d]) # TODO: is d a source variable? return d elif isinstance(e, ir.Binop) and e.operation == '*': a = self.munchExpr(e.a) b = self.munchExpr(e.b) d = self.newTmp() - self.emit('mul %d0, %s0, %s1', dst=[d], src=[a, b]) + self.emit('mov %d0, %s0', src=[a], dst=[d]) + self.emit('mul %d0, %s0', dst=[d], src=[b, d]) return d elif isinstance(e, ir.Const) and e.value < 256: d = self.newTmp() self.emit('mov %d0, {}'.format(e.value), dst=[d]) return d + elif isinstance(e, ir.Const) and e.value < (2**31): + d = self.newTmp() + ln = self.frame.addConstant(e.value) + self.emit('ldr %d0, {}'.format(ln), dst=[d]) + return d elif isinstance(e, ir.Mem) and isinstance(e.e, ir.Binop) and \ e.e.operation == '+' and isinstance(e.e.b, ir.Const): base = self.munchExpr(e.e.a) @@ -176,9 +196,9 @@ self.emit('cmp %s0, %s1', src=[a, b]) ntgt = self.targets[s.lab_no] ytgt = self.targets[s.lab_yes] - jmp_ins = makeIns('jmp {}'.format(s.lab_no.name), jumps=[ntgt]) + jmp_ins = makeIns('b {}'.format(s.lab_no.name), jumps=[ntgt]) # Explicitely add fallthrough: - self.emit('jeq %l0', jumps=[ytgt, jmp_ins]) + self.emit('beq {}'.format(s.lab_yes.name), jumps=[ytgt, jmp_ins]) self.emit2(jmp_ins) else: raise NotImplementedError('Stmt --> {}'.format(s)) @@ -266,5 +286,8 @@ for i in frame.instructions: assembler.assemble_line(str(i)) + # TODO: fixup references, do this in another way? + self.outs.backpatch() + self.outs.backpatch() return self.frames diff -r 6f2423df0675 -r 56d37ed4b4d2 python/cortexm3.py --- a/python/cortexm3.py Sat Sep 14 17:29:10 2013 +0200 +++ b/python/cortexm3.py Mon Sep 16 21:51:17 2013 +0200 @@ -111,7 +111,7 @@ @classmethod def Create(cls, vop): - if type(vop) is AUnop and vop.operation == '[]': + if type(vop) is AUnop and vop.operation == '[]' and type(vop.arg) is ABinop and vop.arg.op == '+': vop = vop.arg # descent offset = isRegOffset(cls.regname, vop.arg1, vop.arg2) if type(offset) is int: @@ -121,11 +121,10 @@ elif type(vop) is ASymbol and vop.name.upper() == self.regname: return cls(0) + class MemSpRel(MemRegXRel): regname = 'SP' -class MemPcRel(MemRegXRel): - regname = 'PC' class MemR8Rel: def __init__(self, basereg, offset): @@ -163,8 +162,10 @@ def __init__(self, regs): assert type(regs) is set self.regs = regs + def __repr__(self): return ','.join([str(r) for r in self.regs]) + @classmethod def Create(cls, vop): assert type(vop) is AUnop and vop.operation == '{}' @@ -218,6 +219,7 @@ pc = ArmReg(15, 'pc') armtarget.registers.append(pc) + class ArmInstruction(Instruction): pass @@ -307,7 +309,7 @@ @armtarget.instruction class ldr_pcrel(ArmInstruction): - """ ldr Rt, [PC, imm8], store value into memory """ + """ ldr Rt, LABEL, load value from pc relative position """ mnemonic = 'ldr' operands = (RegOp, LabelRef) def __init__(self, rt, label): @@ -374,13 +376,8 @@ -@armtarget.instruction -class addregregimm3_ins(ArmInstruction): - """ add Rd, Rn, imm3 """ - mnemonic = 'add' - opcode = 3 # 00011 - operands = (RegOp, RegOp, Imm3) - irpattern = 3 +class regregimm3_base(ArmInstruction): + operands = (Reg8Op, Reg8Op, Imm3) def __init__(self, rd, rn, imm3): self.rd = rd self.rn = rn @@ -390,9 +387,24 @@ rn = self.rn.num imm3 = self.imm3.imm opcode = self.opcode - h = (opcode << 11) | (1 << 10) | (imm3 << 6) | (rn << 3) | rd + h = (self.opcode << 9) | (imm3 << 6) | (rn << 3) | rd return u16(h) + +@armtarget.instruction +class addregregimm3_ins(regregimm3_base): + """ add Rd, Rn, imm3 """ + mnemonic = 'add' + opcode = 0b0001110 + + +@armtarget.instruction +class subregregimm3_ins(regregimm3_base): + """ sub Rd, Rn, imm3 """ + mnemonic = 'sub' + opcode = 0b0001111 + + class regregreg_base(ArmInstruction): """ ??? Rd, Rn, Rm """ operands = (Reg8Op, Reg8Op, Reg8Op) @@ -437,6 +449,22 @@ return '{} {}, {}'.format(self.mnemonic, self.rd, self.rm) +@armtarget.instruction +class mulregreg_ins(ArmInstruction): + """ mul Rn, Rdm """ + operands = (Reg8Op, Reg8Op) + mnemonic = 'mul' + def __init__(self, rn, rdm): + self.rn = rn + self.rdm = rdm + def encode(self): + rn = self.rn.num + rdm = self.rdm.num + opcode = 0b0100001101 + h = (opcode << 6) | (rn << 3) | rdm + return u16(h) + def __repr__(self): + return '{} {}, {}'.format(self.mnemonic, self.rdn, self.rm) class regreg_base(ArmInstruction): """ ??? Rdn, Rm """ diff -r 6f2423df0675 -r 56d37ed4b4d2 python/testasm.py --- a/python/testasm.py Sat Sep 14 17:29:10 2013 +0200 +++ b/python/testasm.py Mon Sep 16 21:51:17 2013 +0200 @@ -261,16 +261,29 @@ self.feed('cmp r0, r1') self.check('8842') - def testLeftShit(self): + def testAddimm3(self): + self.feed('add r3, r5, 2') + self.feed('add r4, r1, 6') + self.check('ab1c8c1d') + + def testSubImm3(self): + self.feed('sub r3, r5, 2') + self.feed('sub r4, r1, 6') + self.check('ab1e8c1f') + + def testLeftShift(self): self.feed('lsl r3, r5') self.check('ab40') - def testModSp(self): + def testAddSp(self): self.feed('add sp,sp,8') self.feed('add sp,sp,16') + self.check('02b004b0') + + def testSubSp(self): self.feed('sub sp,sp,32') self.feed('sub sp,sp,4') - self.check('02b004b0 88b081b0') + self.check('88b081b0') def testSequence1(self): self.feed('mov r5, 3') diff -r 6f2423df0675 -r 56d37ed4b4d2 python/testzcc.py --- a/python/testzcc.py Sat Sep 14 17:29:10 2013 +0200 +++ b/python/testzcc.py Mon Sep 16 21:51:17 2013 +0200 @@ -9,13 +9,12 @@ def do(self, fn): """ Compile blink.c3 """ - #args = zcc.parser.parse_args(['-d', 'stm32f4/blink.c3']) - args = zcc.parser.parse_args([fn]) + args = zcc.parser.parse_args([fn, '--package_dir', './c3/examples']) zcc.main(args) def testExamples(self): """ Test all examples in the c3/examples directory """ - example_filenames = glob.glob('./stm32f4/*.c3') + example_filenames = glob.glob('./c3/examples/*.c3') for filename in example_filenames: self.do(filename) diff -r 6f2423df0675 -r 56d37ed4b4d2 python/zcc.py --- a/python/zcc.py Sat Sep 14 17:29:10 2013 +0200 +++ b/python/zcc.py Mon Sep 16 21:51:17 2013 +0200 @@ -59,7 +59,7 @@ res = zcc(src, outs, diag, dumpir=args.dumpir, do_optimize=args.optimize, pack_dir=args.package_dir) if not res: diag.printErrors(src) - sys.exit(1) + return 1 if args.dumpasm: outs.dump() @@ -79,8 +79,9 @@ hf = hexfile.HexFile() hf.addRegion(0x08000000, code_bytes) hf.save(args.hexfile) + return 0 if __name__ == '__main__': arguments = parser.parse_args() - main(arguments) + sys.exit(main(arguments))