ARM: Link register is trashed by non-executed branch and link operations.
authorJack Whitman <jack-m5ml2@cs.york.ac.uk>
Thu, 25 Jun 2009 04:22:46 +0000 (21:22 -0700)
committerJack Whitman <jack-m5ml2@cs.york.ac.uk>
Thu, 25 Jun 2009 04:22:46 +0000 (21:22 -0700)
src/arch/arm/isa/decoder.isa
src/arch/arm/isa/formats/branch.isa

index af325b57adaba0c6f3d1d3f93427d486b8234fc1..20f5b99f09cea44f5b9aedfa20bb5778b463b237 100644 (file)
@@ -246,7 +246,7 @@ decode COND_CODE default Unknown::unknown() {
                                 }});
                             }
                             0x3: decode OPCODE_24_21 {
-                                0x9: BranchExchange::blx({{ LR = NPC; }});
+                                0x9: BranchExchange::blx({{ }}, Link);
                             }
                         }
                         }
@@ -661,7 +661,7 @@ decode COND_CODE default Unknown::unknown() {
         0x5: decode OPCODE_24 {
             // Branch (and Link) Instructions
             0: Branch::b({{ }});
-            1: Branch::bl({{ LR = NPC; }});
+            1: Branch::bl({{ }}, Link);
         }
         0x6: decode CPNUM {
             0x1: decode PUNWL {
index b8fbb982d0f4c00538f681c130f2e46927b140d6..95f4f14e192756a10478cbece71df4ce0b15b695 100644 (file)
@@ -38,8 +38,10 @@ def format Branch(code,*opt_flags) {{
     #Build Instruction Flags
     #Use Link & Likely Flags to Add Link/Condition Code
     inst_flags = ('IsDirectControl', )
+    linking = False
     for x in opt_flags:
         if x == 'Link':
+            linking = True
             code += 'LR = NPC;\n'
         else:
             inst_flags += (x, )
@@ -55,6 +57,8 @@ def format Branch(code,*opt_flags) {{
     icode += '  NPC = NPC + 4 + disp;\n'
     icode += '} else {\n'
     icode += '  NPC = NPC;\n'
+    if linking:
+        icode += '  LR = LR;\n'
     icode += '};\n'
 
     code = icode
@@ -70,8 +74,10 @@ def format BranchExchange(code,*opt_flags) {{
     #Build Instruction Flags
     #Use Link & Likely Flags to Add Link/Condition Code
     inst_flags = ('IsIndirectControl', )
+    linking = False
     for x in opt_flags:
         if x == 'Link':
+            linking = True
             code += 'LR = NPC;\n'
         else:
             inst_flags += (x, )
@@ -89,6 +95,8 @@ def format BranchExchange(code,*opt_flags) {{
     icode += '  NPC = Rm & 0xfffffffe; // Masks off bottom bit\n'
     icode += '} else {\n'
     icode += '  NPC = NPC;\n'
+    if linking:
+        icode += '  LR = LR;\n'
     icode += '};\n'
 
     code = icode