In Thumb2, direct branches can be encoded as either a "short" conditional branch...
[oota-llvm.git] / lib / Target / ARM / ARMAsmBackend.cpp
index f14a156b57b5b2d5744c54c1be3d666f7c609fb9..cb0c54386ed67e95d7663b157d773d7d5ef039cd 100644 (file)
@@ -140,10 +140,31 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
     // These values don't encode the low two bits since they're always zero.
     // Offset by 8 just as above.
     return 0xffffff & ((Value - 8) >> 2);
-  case ARM::fixup_t2_branch: {
+  case ARM::fixup_t2_uncondbranch: {
     Value = Value - 4;
     Value >>= 1; // Low bit is not encoded.
 
+    uint32_t out = 0;
+    bool I =  Value & 0x800000;
+    bool J1 = Value & 0x400000;
+    bool J2 = Value & 0x200000;
+    J1 ^= I;
+    J2 ^= I;
+    
+    out |= I  << 26; // S bit
+    out |= !J1 << 13; // J1 bit
+    out |= !J2 << 11; // J2 bit
+    out |= (Value & 0x1FF800)  << 5; // imm6 field
+    out |= (Value & 0x0007FF);        // imm11 field
+    
+    uint64_t swapped = (out & 0xFFFF0000) >> 16;
+    swapped |= (out & 0x0000FFFF) << 16;
+    return swapped;
+  }
+  case ARM::fixup_t2_condbranch: {
+    Value = Value - 4;
+    Value >>= 1; // Low bit is not encoded.
+    
     uint64_t out = 0;
     out |= (Value & 0x80000) << 7; // S bit
     out |= (Value & 0x40000) >> 7; // J2 bit
@@ -151,7 +172,7 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
     out |= (Value & 0x1F800) << 5; // imm6 field
     out |= (Value & 0x007FF);      // imm11 field
 
-    uint64_t swapped = (out & 0xFFFF0000) >> 16;
+    uint32_t swapped = (out & 0xFFFF0000) >> 16;
     swapped |= (out & 0x0000FFFF) << 16;
     return swapped;
   }
@@ -226,7 +247,7 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) {
     // Same addressing mode as fixup_arm_pcrel_10,
     // but with 16-bit halfwords swapped.
     if (Kind == ARM::fixup_t2_pcrel_10) {
-      uint64_t swapped = (Value & 0xFFFF0000) >> 16;
+      uint32_t swapped = (Value & 0xFFFF0000) >> 16;
       swapped |= (Value & 0x0000FFFF) << 16;
       return swapped;
     }
@@ -332,7 +353,8 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
 
   case FK_Data_4:
   case ARM::fixup_t2_ldst_pcrel_12:
-  case ARM::fixup_t2_branch:
+  case ARM::fixup_t2_condbranch:
+  case ARM::fixup_t2_uncondbranch:
   case ARM::fixup_t2_pcrel_10:
   case ARM::fixup_arm_thumb_bl:
   case ARM::fixup_arm_thumb_blx: