diff python/target/armtarget.py @ 341:4d204f6f7d4e devel

Rewrite of assembler parts
author Windel Bouwman
date Fri, 28 Feb 2014 18:07:14 +0100
parents c7cc54c0dfdf
children
line wrap: on
line diff
--- a/python/target/armtarget.py	Sun Feb 23 16:24:01 2014 +0100
+++ b/python/target/armtarget.py	Fri Feb 28 18:07:14 2014 +0100
@@ -1,11 +1,16 @@
 import struct
-from .basetarget import Register, Instruction, Target, Label, LabelRef
+from .basetarget import Register, Instruction, Target, Label, Alignment
 from .basetarget import Imm32, Imm8, Imm7, Imm3
-from .arminstructions import allins, Reg8Op, ArmRegister
-from .arminstructions import thumb_assembly_rules
+from .arminstructions import Add2, Sub, Add3, Cmp, Lsl, Orr
+from .arminstructions import Dcd, Pop, Push, Yield, Mov2, Mov3
+from .arminstructions import B, Bl, Bne, Beq, Blt, Bgt
+from .arminstructions import Ldr, Str2, Ldr2, Str1, Ldr1
 
 from .armframe import ArmFrame
 from .arminstructionselector import ArmInstructionSelector
+from .armregisters import R0, R1, R2, R3, R4, R5, R6, R7, SP, LR, PC
+from .armregisters import register_range
+
 
 """ ARM target description. """
 
@@ -13,21 +18,171 @@
 # TBD: is this required?
 # TODO: make a difference between armv7 and armv5?
 
+thumb_assembly_rules = []
+def add_rule(rhs, f):
+    thumb_assembly_rules.append(('instruction', rhs, f))
 
-class ArmThumbTarget(Target):
+
+class ThumbTarget(Target):
     def __init__(self):
-        super().__init__('arm_thumb')
-        for i in allins:
-            self.addInstruction(i)
-            # TODO: fix this nicer?
-            #setattr(self, i.__name__, i)
-        self.check()
+        super().__init__('thumb')
         self.ins_sel = ArmInstructionSelector()
         self.FrameClass = ArmFrame
-        self.assembler_rules = thumb_assembly_rules
+        self.add_rules()
+
+    def add_rules(self):
+
+        # Add instructions:
+        self.add_keyword('dcd')
+        self.add_instruction(['dcd', 'imm32'], lambda rhs: Dcd(rhs[1]))
+
+        self.add_keyword('mov')
+        self.add_instruction(['mov', 'reg8', ',', 'reg8'],
+                lambda rhs: Mov2(rhs[1], rhs[3]))
+
+        self.add_instruction(['mov', 'reg8', ',', 'imm8'],
+                lambda rhs: Mov3(rhs[1], rhs[3]))
+
+        self.add_keyword('add')
+        self.add_instruction(['add', 'reg8', ',', 'reg8', ',', 'imm3'],
+                lambda rhs: Add2(rhs[1], rhs[3], rhs[5]))
+
+        self.add_instruction(['add', 'reg8', ',', 'reg8', ',', 'reg8'],
+                lambda rhs: Add3(rhs[1], rhs[3], rhs[5]))
+
+        self.add_keyword('sub')
+        self.add_instruction(['sub', 'reg8', ',', 'reg8', ',', 'imm3'],
+                lambda rhs: Sub(rhs[1], rhs[3], rhs[5]))
+
+        self.add_instruction(['sub', 'sp', ',', 'sp', ',', 'imm8'],
+                lambda rhs: Sub(SP, SP, rhs[5]))
+
+        self.add_instruction(['add', 'sp', ',', 'sp', ',', 'imm8'],
+                lambda rhs: Sub(SP, SP, rhs[5]))
+
+        self.add_keyword('cmp')
+        self.add_instruction(['cmp', 'reg8', ',', 'reg8'],
+                lambda rhs: Cmp(rhs[1], rhs[3]))
+
+        self.add_keyword('lsl')
+        self.add_instruction(['lsl', 'reg8', ',', 'reg8'],
+                lambda rhs: Lsl(rhs[1], rhs[3]))
+
+        self.add_keyword('str')
+        self.add_instruction(['str', 'reg8', ',', '[', 'reg8', '+', 'imm5', ']'],
+                lambda rhs: Str2(rhs[1], rhs[4], rhs[6]))
+
+        self.add_keyword('ldr')
+        self.add_instruction(['ldr', 'reg8', ',', '[', 'reg8', '+', 'imm5', ']'],
+                lambda rhs: Ldr2(rhs[1], rhs[4], rhs[6]))
+
+        self.add_instruction(['str', 'reg8', ',', '[', 'sp', '+', 'imm8', ']'],
+                lambda rhs: Str1(rhs[1], rhs[6]))
+
+        self.add_instruction(['ldr', 'reg8', ',', '[', 'sp', '+', 'imm8', ']'],
+                lambda rhs: Ldr1(rhs[1], rhs[6]))
+
+        self.add_keyword('pop')
+        self.add_instruction(['pop', 'reg_list'], lambda rhs: Pop(rhs[1]))
+        self.add_keyword('push')
+        self.add_instruction(['push', 'reg_list'], lambda rhs: Push(rhs[1]))
+
+        self.add_keyword('yield')
+        self.add_instruction(['yield'], lambda rhs: Yield())
+
+        self.add_keyword('b')
+        self.add_keyword('bl')
+        self.add_instruction(['b', 'ID'], lambda rhs: B(rhs[1].val))
+        self.add_instruction(['bl', 'ID'], lambda rhs: Bl(rhs[1].val))
+        self.add_keyword('beq')
+        self.add_keyword('bne')
+        self.add_keyword('blt')
+        self.add_keyword('bgt')
+        self.add_instruction(['beq', 'ID'], lambda rhs: Beq(rhs[1].val))
+        self.add_instruction(['bne', 'ID'], lambda rhs: Bne(rhs[1].val))
+        self.add_instruction(['blt', 'ID'], lambda rhs: Blt(rhs[1].val))
+        self.add_instruction(['bgt', 'ID'], lambda rhs: Bgt(rhs[1].val))
+
+        self.add_keyword('align')
+        self.add_instruction(['align', 'imm8'], lambda rhs: Alignment(rhs[1]))
+
+        self.add_instruction(['ldr', 'reg8', ',', 'ID'],
+                lambda rhs: Ldr(rhs[1], rhs[3].val))
+
+        # Additional rules:
+
+        # Register list grammar:
+        self.add_rule('reg_list', ['{', 'reg_list_inner', '}'],
+            lambda rhs: rhs[1])
+        self.add_rule('reg_list_inner', ['reg_or_range'],
+            lambda rhs: rhs[0])
+        self.add_rule('reg_list_inner', ['reg_or_range', ',', 'reg_list_inner'],
+            lambda rhs: rhs[0] | rhs[2])
+        self.add_rule('reg_or_range', ['reg8'], lambda rhs: {rhs[0]})
+        self.add_rule('reg_or_range', ['lr'], lambda rhs: {LR})
+        self.add_rule('reg_or_range', ['pc'], lambda rhs: {PC})
+
+        self.add_rule('reg_or_range', ['reg8', '-', 'reg8'],
+            lambda rhs: register_range(rhs[0], rhs[2]))
+
+        self.add_keyword('r0')
+        self.add_keyword('r1')
+        self.add_keyword('r2')
+        self.add_keyword('r3')
+        self.add_keyword('r4')
+        self.add_keyword('r5')
+        self.add_keyword('r6')
+        self.add_keyword('r7')
+        self.add_keyword('sp')
+        self.add_keyword('lr')
+        self.add_keyword('pc')
+        self.add_rule('reg8', ['r0'], lambda rhs: R0)
+        self.add_rule('reg8', ['r1'], lambda rhs: R1)
+        self.add_rule('reg8', ['r2'], lambda rhs: R2)
+        self.add_rule('reg8', ['r3'], lambda rhs: R3)
+        self.add_rule('reg8', ['r4'], lambda rhs: R4)
+        self.add_rule('reg8', ['r5'], lambda rhs: R5)
+        self.add_rule('reg8', ['r6'], lambda rhs: R6)
+        self.add_rule('reg8', ['r7'], lambda rhs: R7)
+        # Constants:
+        self.add_rule('imm32', ['val32'], lambda x: x[0].val)
+        self.add_rule('imm32', ['imm8'], lambda x: x[0])
+        self.add_rule('imm8', ['val8'], lambda x: x[0].val)
+        self.add_rule('imm8', ['imm5'], lambda x: x[0])
+        self.add_rule('imm5', ['val5'], lambda x: x[0].val)
+        self.add_rule('imm5', ['imm3'], lambda x: x[0])
+        self.add_rule('imm3', ['val3'], lambda x: x[0].val)
+
 
 
 class ArmArmTarget(Target):
     def __init__(self):
         super().__init__('arm_arm')
 
+        # Assembly grammar:
+        self.add_keyword('mov')
+        self.add_keyword('r0')
+        self.add_keyword('r1')
+        self.add_keyword('r2')
+        self.add_keyword('r3')
+        self.add_keyword('r4')
+        self.add_keyword('r5')
+
+        self.add_rule('reg', ['r0'], lambda rhs: R0)
+        self.add_rule('reg', ['r1'], lambda rhs: R1)
+        self.add_rule('reg', ['r2'], lambda rhs: R2)
+        self.add_rule('reg', ['r3'], lambda rhs: R3)
+        self.add_rule('reg', ['r4'], lambda rhs: R4)
+        self.add_rule('reg', ['r5'], lambda rhs: R5)
+
+
+        self.add_instruction(['mov', 'reg', ',', 'imm8'],
+                lambda rhs: Yield())
+
+        self.add_rule('imm32', ['val32'], lambda x: x[0].val)
+        self.add_rule('imm32', ['imm8'], lambda x: x[0])
+        self.add_rule('imm8', ['val8'], lambda x: x[0].val)
+        self.add_rule('imm8', ['imm5'], lambda x: x[0])
+        self.add_rule('imm5', ['val5'], lambda x: x[0].val)
+        self.add_rule('imm5', ['imm3'], lambda x: x[0])
+        self.add_rule('imm3', ['val3'], lambda x: x[0].val)