Skip to content

Commit 16125b4

Browse files
clazissartemiy-volkov
authored andcommitted
[PIC] Add pic support for variables
1 parent 5558063 commit 16125b4

File tree

4 files changed

+101
-18
lines changed

4 files changed

+101
-18
lines changed

gcc/config/arc64/arc64.c

Lines changed: 76 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,12 @@ arc64_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
487487
if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY))
488488
return true;
489489

490+
/* PIC address. */
491+
if (GET_CODE (x) == LO_SUM
492+
&& REG_P (XEXP (x, 0))
493+
&& GET_CODE (XEXP (x, 1)) == UNSPEC)
494+
return true;
495+
490496
return false;
491497
}
492498

@@ -933,7 +939,8 @@ arc64_print_operand (FILE *file, rtx x, int code)
933939

934940
case 'h':
935941
if (GET_CODE (x) == SYMBOL_REF
936-
|| GET_CODE (x) == LABEL_REF)
942+
|| GET_CODE (x) == LABEL_REF
943+
|| GET_CODE (x) == UNSPEC)
937944
{
938945
output_addr_const (asm_out_file, x);
939946
break;
@@ -971,6 +978,7 @@ arc64_print_operand (FILE *file, rtx x, int code)
971978

972979
case LABEL_REF:
973980
case SYMBOL_REF:
981+
case UNSPEC:
974982
output_addr_const (asm_out_file, x);
975983
break;
976984

@@ -1039,16 +1047,14 @@ arc64_print_operand_address (FILE *file , machine_mode mode, rtx addr)
10391047
output_address (VOIDmode, XEXP (addr, 1));
10401048
break;
10411049

1042-
#if 0
10431050
/* This type of address can be only accepted by LD instructions. */
10441051
case LO_SUM:
1045-
base = XEXP (addr,0);
1046-
index = XEXP (addr,1);
1052+
base = XEXP (addr, 0);
1053+
index = XEXP (addr, 1);
10471054
arc64_print_operand_address (file, mode, base);
10481055
fputc (',', file);
10491056
output_addr_const (file, index);
10501057
break;
1051-
#endif
10521058

10531059
case CONST_INT:
10541060
output_addr_const (file, addr);
@@ -1069,6 +1075,44 @@ arc64_print_operand_punct_valid_p (unsigned char code)
10691075
return (code == '?');
10701076
}
10711077

1078+
/* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
1079+
1080+
static bool
1081+
arc64_output_addr_const_extra (FILE *file, rtx x)
1082+
{
1083+
rtx base;
1084+
1085+
if (GET_CODE (x) == UNSPEC)
1086+
{
1087+
base = XVECEXP (x, 0, 0);
1088+
output_addr_const (file, base);
1089+
switch (XINT (x, 1))
1090+
{
1091+
case ARC64_UNSPEC_GOTOFF:
1092+
fputs ("@pcl", file);
1093+
break;
1094+
1095+
case ARC64_UNSPEC_GOT:
1096+
fputs ("@gotpc", file);
1097+
break;
1098+
1099+
default:
1100+
gcc_unreachable ();
1101+
}
1102+
return true;
1103+
}
1104+
1105+
return false;
1106+
}
1107+
1108+
/* Wrap X in an unspec of kind KIND. */
1109+
1110+
static rtx
1111+
gen_sym_unspec (rtx x, int kind)
1112+
{
1113+
return gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), kind);
1114+
}
1115+
10721116
/* Helper function. Returns a valid ARC64 RTX that represents the
10731117
argument X which is an invalid address RTX. The argument SCRATCH
10741118
may be used as a temp when building affresses. */
@@ -1077,15 +1121,37 @@ static rtx
10771121
arc64_legitimize_address_1 (rtx x, rtx scratch)
10781122
{
10791123
rtx base, addend, t1;
1124+
bool is_local = true;
10801125

10811126
switch (GET_CODE (x))
10821127
{
10831128
case SYMBOL_REF:
1129+
is_local = SYMBOL_REF_LOCAL_P (x);
1130+
/* FALLTHRU */
1131+
10841132
case LABEL_REF:
10851133
t1 = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : scratch;
10861134
gcc_assert (t1);
1087-
emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, x)));
1088-
return gen_rtx_LO_SUM (Pmode, t1, x);
1135+
if (!flag_pic)
1136+
{
1137+
emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, x)));
1138+
return gen_rtx_LO_SUM (Pmode, t1, x);
1139+
}
1140+
else if (is_local)
1141+
{
1142+
/* Local symbol, we can access it using a simple
1143+
PCL-relative access. */
1144+
base = gen_sym_unspec (x, ARC64_UNSPEC_GOTOFF);
1145+
return base;
1146+
}
1147+
else
1148+
{
1149+
/* Global symbol, we access it via a load from the GOT. */
1150+
base = gen_sym_unspec (x, ARC64_UNSPEC_GOT);
1151+
emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, base)));
1152+
t1 = gen_rtx_LO_SUM (Pmode, t1, copy_rtx (base));
1153+
return gen_const_mem (Pmode, t1);
1154+
}
10891155

10901156
case LO_SUM:
10911157
return x;
@@ -1801,6 +1867,9 @@ arc64_limm_addr_p (rtx op)
18011867
#undef TARGET_PROMOTE_PROTOTYPES
18021868
#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
18031869

1870+
#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
1871+
#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA arc64_output_addr_const_extra
1872+
18041873
struct gcc_target targetm = TARGET_INITIALIZER;
18051874

18061875
#include "gt-arc64.h"

gcc/config/arc64/arc64.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@
7070

7171
(define_c_enum "unspec"
7272
[
73-
VUNSPEC_ARC_BLOCKAGE
73+
ARC64_UNSPEC_GOTOFF
74+
ARC64_UNSPEC_GOT
75+
ARC64_VUNSPEC_BLOCKAGE
7476
])
7577

7678
(include "constraints.md")
@@ -364,8 +366,8 @@ udivl, unknown, xor, xorl"
364366
;; Long insns: movl, stl, ldl
365367
;;
366368
(define_insn "*arc64_movdi"
367-
[(set (match_operand:DI 0 "nonimmediate_operand" "=qh, q,r, r, r,r, m")
368-
(match_operand:DI 1 "arc64_movl_operand" "qh,U08S0,r,S12S0,S32S0,m, r"))]
369+
[(set (match_operand:DI 0 "nonimmediate_operand" "=qh, q,r, r, r, r,r, m")
370+
(match_operand:DI 1 "arc64_movl_operand" "qh,U08S0,r,S12S0,S32S0,SyPic,m, r"))]
369371
"register_operand (operands[0], DImode)
370372
|| register_operand (operands[1], DImode)"
371373
"@
@@ -374,25 +376,27 @@ udivl, unknown, xor, xorl"
374376
movl\\t%0,%1
375377
movl\\t%0,%1
376378
movl\\t%0,%1
379+
addl\\t%0,pcl,%1
377380
ldl%U1\\t%0,[%1]
378381
stl%U0\\t%1,[%0]"
379-
[(set_attr "type" "move,move,move,move,move,ld,st")
380-
(set_attr "length" "2,2,4,4,8,*,*")]
382+
[(set_attr "type" "move,move,move,move,move,addl,ld,st")
383+
(set_attr "length" "2,2,4,4,8,8,*,*")]
381384
)
382385

383386
;; Hi/Low moves for constant and symbol loading.
384387

385388
(define_insn "*movdi_high"
386-
[(set (match_operand:DI 0 "register_operand" "= r, qh, r")
389+
[(set (match_operand:DI 0 "register_operand" "= r, qh, r,r")
387390
(high:DI
388-
(match_operand:DI 1 "immediate_operand" "S12S0,SymIm,SymIm")))]
391+
(match_operand:DI 1 "arc64_immediate_or_pic" "S12S0,SymIm,SymIm,SyPic")))]
389392
""
390393
"@
391394
movhl\\t%0,%h1
392395
movhl_s\\t%0,%h1
393-
movhl\\t%0,%h1"
396+
movhl\\t%0,%h1
397+
addhl\\t%0,pcl,%h1"
394398
[(set_attr "type" "move")
395-
(set_attr "length" "4,6,8")])
399+
(set_attr "length" "4,6,8,8")])
396400

397401
;; The immediates are already trimmed to fit the 32 bit limm field.
398402
(define_insn "*movdi_high"
@@ -655,7 +659,7 @@ udivl, unknown, xor, xorl"
655659
(set_attr "length" "2")])
656660

657661
(define_insn "blockage"
658-
[(unspec_volatile [(const_int 0)] VUNSPEC_ARC_BLOCKAGE)]
662+
[(unspec_volatile [(const_int 0)] ARC64_VUNSPEC_BLOCKAGE)]
659663
""
660664
""
661665
[(set_attr "length" "0")

gcc/config/arc64/constraints.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@
104104
(match_code "const_int")
105105
(match_test "SIGNED_INT6 (ival)")))
106106

107+
(define_constraint "SyPic"
108+
"@internal
109+
Special symbol used for PIC addressing."
110+
(match_code "unspec"))
107111
;---------------------------------------------------------
108112

109113
(define_constraint "U06S0" "@internal

gcc/config/arc64/predicates.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020

2121
;; Place holder for mov operand predicate
2222
(define_predicate "arc64_movl_operand"
23-
(and (match_code "reg, subreg, mem, const, const_int, symbol_ref, label_ref")
23+
(and (match_code "unspec,reg, subreg, mem, const, const_int, symbol_ref, label_ref")
2424
(ior (match_operand 0 "register_operand")
2525
(match_operand 0 "memory_operand")
26+
(match_code "unspec")
2627
(and (match_code "const_int")
2728
(ior (match_test "UNSIGNED_INT32 (INTVAL (op))")
2829
(match_test "SIGNED_INT32 (INTVAL (op))"))))))
@@ -33,6 +34,11 @@
3334
(ior (match_test "UNSIGNED_INT32 (INTVAL (op))")
3435
(match_test "SIGNED_INT32 (INTVAL (op))")))))
3536

37+
;; Used for HIGH or LO_SUM patterns
38+
(define_predicate "arc64_immediate_or_pic"
39+
(ior (match_operand 0 "immediate_operand")
40+
(match_code "unspec")))
41+
3642
;; Acceptable arguments for the call insn.
3743
(define_predicate "arc64_call_insn_operand"
3844
(ior (match_code "symbol_ref")

0 commit comments

Comments
 (0)