changeset 276:56d37ed4b4d2

phaa
author Windel Bouwman
date Mon, 16 Sep 2013 21:51:17 +0200
parents 6f2423df0675
children 046017431c6a
files python/codegenarm.py python/cortexm3.py python/testasm.py python/testzcc.py python/zcc.py
diffstat 5 files changed, 89 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- 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
 
--- 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 """
--- 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')
--- 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)
 
--- 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))