OSDN Git Service

Mips specific standalone assembler addressing mode %hi and %lo.
authorJack Carter <jcarter@mips.com>
Thu, 21 Feb 2013 02:09:31 +0000 (02:09 +0000)
committerJack Carter <jcarter@mips.com>
Thu, 21 Feb 2013 02:09:31 +0000 (02:09 +0000)
The constructs %hi() and %lo() represent the high and low 16
bits of the address.
Because the 16 bit offset field of an LW instruction is
interpreted as signed, if bit 15 of the low part is 1 then the
low part will act as a negative and 1 needs to be added to the
high part.

Contributer: Vladimir Medic

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175707 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/AsmParser/MipsAsmParser.cpp
test/MC/Mips/hilo-addressing.s [new file with mode: 0644]
test/MC/Mips/mips_directives.s

index 088589f..ade6084 100644 (file)
@@ -888,7 +888,12 @@ bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
     if (Str == "lo") {
       Val = Val & 0xffff;
     } else if (Str == "hi") {
+      int LoSign = Val & 0x8000;
       Val = (Val & 0xffff0000) >> 16;
+      //lower part is treated as signed int, so if it is negative
+      //we must add 1 to hi part to compensate
+      if (LoSign)
+        Val++;
     }
     Res = MCConstantExpr::Create(Val, getContext());
     return false;
diff --git a/test/MC/Mips/hilo-addressing.s b/test/MC/Mips/hilo-addressing.s
new file mode 100644 (file)
index 0000000..28459c2
--- /dev/null
@@ -0,0 +1,11 @@
+# RUN: llvm-mc -show-encoding -triple mips-unknown-unknown %s | FileCheck %s
+
+  .ent hilo_test
+     .equ    addr, 0xdeadbeef
+# CHECK: # encoding: [0x3c,0x04,0xde,0xae]
+    lui $4,%hi(addr)
+# CHECK: # encoding: [0x03,0xe0,0x00,0x08]
+    jr  $31
+# CHECK: # encoding: [0x80,0x82,0xbe,0xef]
+    lb  $2,%lo(addr)($4)
+    .end hilo_test
index d0a3bea..65d584d 100644 (file)
@@ -1,5 +1,5 @@
-# RUN: llvm-mc -triple mips-unknown-unknown %s | FileCheck %s
-#this test produces no output so there isS no FileCheck call
+# RUN: llvm-mc -show-encoding -triple mips-unknown-unknown %s | FileCheck %s
+#
 $BB0_2:
   .ent directives_test
     .frame    $sp,0,$ra
@@ -17,4 +17,3 @@ $JTI0_0:
     .set macro
     .set reorder
     .set  at=$a0
-    .end directives_test