Hi,

Adding support for tiny model GOT access.  Regressed, committed.

/Marcus

2013-07-15  Marcus Shawcroft  <marcus.shawcr...@arm.com>

        * config/aarch64/aarch64-protos.h (aarch64_symbol_type):
        Define SYMBOL_TINY_GOT, update comment.
        * config/aarch64/aarch64.c
        (aarch64_load_symref_appropriately): Handle SYMBOL_TINY_GOT.
        (aarch64_expand_mov_immediate): Likewise.
        (aarch64_print_operand): Likewise.
        (aarch64_classify_symbol): Likewise.
        * config/aarch64/aarch64.md (UNSPEC_GOTTINYPIC): Define.
        (ldr_got_tiny): Define.
diff --git a/gcc/config/aarch64/aarch64-protos.h 
b/gcc/config/aarch64/aarch64-protos.h
index e749cc1..f19045d 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -75,6 +75,17 @@ enum aarch64_symbol_context
 
    ADR x0, foo
 
+   SYMBOL_TINY_GOT
+
+   Generate symbol accesses via the GOT using a single PC relative
+   instruction.  To compute the address of symbol foo, we generate:
+
+   ldr t0, :got:foo
+
+   The value of foo can subsequently read using:
+
+   ldrb    t0, [t0]
+
    SYMBOL_FORCE_TO_MEM : Global variables are addressed using
    constant pool.  All variable addresses are spilled into constant
    pools.  The constant pools themselves are addressed using PC
@@ -89,6 +100,7 @@ enum aarch64_symbol_type
   SYMBOL_SMALL_GOTTPREL,
   SYMBOL_SMALL_TPREL,
   SYMBOL_TINY_ABSOLUTE,
+  SYMBOL_TINY_GOT,
   SYMBOL_FORCE_TO_MEM
 };
 
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 03e5f19..ec9906f 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -641,6 +641,10 @@ aarch64_load_symref_appropriately (rtx dest, rtx imm,
        return;
       }
 
+    case SYMBOL_TINY_GOT:
+      emit_insn (gen_ldr_got_tiny (dest, imm));
+      return;
+
     default:
       gcc_unreachable ();
     }
@@ -920,6 +924,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
         case SYMBOL_SMALL_TLSDESC:
         case SYMBOL_SMALL_GOTTPREL:
        case SYMBOL_SMALL_GOT:
+       case SYMBOL_TINY_GOT:
          if (offset != const0_rtx)
            {
              gcc_assert(can_create_pseudo_p ());
@@ -3694,6 +3699,10 @@ aarch64_print_operand (FILE *f, rtx x, char code)
          asm_fprintf (asm_out_file, ":tprel:");
          break;
 
+       case SYMBOL_TINY_GOT:
+         gcc_unreachable ();
+         break;
+
        default:
          break;
        }
@@ -3723,6 +3732,10 @@ aarch64_print_operand (FILE *f, rtx x, char code)
          asm_fprintf (asm_out_file, ":tprel_lo12_nc:");
          break;
 
+       case SYMBOL_TINY_GOT:
+         asm_fprintf (asm_out_file, ":got:");
+         break;
+
        default:
          break;
        }
@@ -5295,7 +5308,7 @@ aarch64_classify_symbol (rtx x,
 
        case AARCH64_CMODEL_TINY_PIC:
          if (!aarch64_symbol_binds_local_p (x))
-           return SYMBOL_SMALL_GOT;
+           return SYMBOL_TINY_GOT;
          return SYMBOL_TINY_ABSOLUTE;
 
        case AARCH64_CMODEL_SMALL_PIC:
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 54f4af1..233014e 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -80,6 +80,7 @@
     UNSPEC_FRINTZ
     UNSPEC_GOTSMALLPIC
     UNSPEC_GOTSMALLTLS
+    UNSPEC_GOTTINYPIC
     UNSPEC_LD2
     UNSPEC_LD3
     UNSPEC_LD4
@@ -3783,6 +3784,16 @@
    (set_attr "mode" "DI")]
 )
 
+(define_insn "ldr_got_tiny"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (unspec:DI [(match_operand:DI 1 "aarch64_valid_symref" "S")]
+                  UNSPEC_GOTTINYPIC))]
+  ""
+  "ldr\\t%0, %L1"
+  [(set_attr "v8type" "load1")
+   (set_attr "mode" "DI")]
+)
+
 (define_insn "aarch64_load_tp_hard"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (unspec:DI [(const_int 0)] UNSPEC_TLS))]

Reply via email to