Skip to content

Commit 2e6830a

Browse files
clazissartemiy-volkov
authored andcommitted
[PIC] Add small/large PIC memory model.
1 parent 4ffd645 commit 2e6830a

File tree

6 files changed

+122
-7
lines changed

6 files changed

+122
-7
lines changed

gcc/config/arc64/arc64-opts.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* Copyright (C) 2019 Free Software Foundation, Inc.
2+
3+
This file is part of GCC.
4+
5+
GCC is free software; you can redistribute it and/or modify it
6+
under the terms of the GNU General Public License as published
7+
by the Free Software Foundation; either version 3, or (at your
8+
option) any later version.
9+
10+
GCC is distributed in the hope that it will be useful, but WITHOUT
11+
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12+
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13+
License for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with GCC; see the file COPYING3. If not see
17+
<http://www.gnu.org/licenses/>. */
18+
19+
20+
/* The code model defines the address generation strategy. */
21+
enum arc64_code_model {
22+
/* Static code and data fit within a 1MB region.
23+
The default non-PIC code model. */
24+
ARC64_CMODEL_SMALL,
25+
/* The default for PIC code model, static code and data fit within
26+
4GB region. Local calls will fit within 16MB region. */
27+
ARC64_CMODEL_MEDIUM,
28+
/* No assumptions about addresses of code and data. */
29+
ARC64_CMODEL_LARGE
30+
};

gcc/config/arc64/arc64-protos.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ extern bool arc64_prepare_move_operands (rtx, rtx, machine_mode);
1919
extern void arc64_expand_prologue (void);
2020
extern void arc64_expand_epilogue (bool);
2121
extern bool arc64_limm_addr_p (rtx);
22+
extern bool arc64_is_long_call_p (rtx);
2223

2324
#endif /* RTX_CODE */
2425

gcc/config/arc64/arc64.c

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -487,12 +487,17 @@ 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. */
490+
/* PIC address (LARGE). */
491491
if (GET_CODE (x) == LO_SUM
492492
&& REG_P (XEXP (x, 0))
493493
&& GET_CODE (XEXP (x, 1)) == UNSPEC)
494494
return true;
495495

496+
/* PIC address (small). */
497+
if (GET_CODE (x) == UNSPEC
498+
&& XINT (x, 1) == ARC64_UNSPEC_GOT32)
499+
return true;
500+
496501
return false;
497502
}
498503

@@ -1062,15 +1067,21 @@ arc64_print_operand_address (FILE *file , machine_mode mode, rtx addr)
10621067
output_address (VOIDmode, XEXP (addr, 1));
10631068
break;
10641069

1065-
/* This type of address can be only accepted by LD instructions. */
10661070
case LO_SUM:
1071+
/* This type of address can be only accepted by LD instructions. */
10671072
base = XEXP (addr, 0);
10681073
index = XEXP (addr, 1);
10691074
arc64_print_operand_address (file, mode, base);
10701075
fputc (',', file);
10711076
output_addr_const (file, index);
10721077
break;
10731078

1079+
case UNSPEC:
1080+
/* Small PIC. */
1081+
fputs ("pcl,", file);
1082+
output_addr_const (file, addr);
1083+
break;
1084+
10741085
case CONST_INT:
10751086
output_addr_const (file, addr);
10761087
break;
@@ -1107,6 +1118,7 @@ arc64_output_addr_const_extra (FILE *file, rtx x)
11071118
fputs ("@pcl", file);
11081119
break;
11091120

1121+
case ARC64_UNSPEC_GOT32:
11101122
case ARC64_UNSPEC_GOT:
11111123
fputs ("@gotpc", file);
11121124
break;
@@ -1159,9 +1171,17 @@ arc64_legitimize_address_1 (rtx x, rtx scratch)
11591171
base = gen_sym_unspec (x, ARC64_UNSPEC_GOTOFF);
11601172
return base;
11611173
}
1174+
else if (flag_pic == 1)
1175+
{
1176+
/* Global symbol, we access it via a load from the GOT
1177+
(small model). */
1178+
base = gen_sym_unspec (x, ARC64_UNSPEC_GOT32);
1179+
return gen_const_mem (Pmode, base);
1180+
}
11621181
else
11631182
{
1164-
/* Global symbol, we access it via a load from the GOT. */
1183+
/* Global symbol, we access it via a load from the GOT
1184+
(LARGE model). */
11651185
base = gen_sym_unspec (x, ARC64_UNSPEC_GOT);
11661186
emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, base)));
11671187
t1 = gen_rtx_LO_SUM (Pmode, t1, copy_rtx (base));
@@ -1381,11 +1401,35 @@ arc64_output_function_prologue (FILE *f)
13811401
}
13821402
}
13831403

1384-
13851404
/*
13861405
Global functions.
13871406
*/
13881407

1408+
/* Returns TRUE if CALLEE should be treated as long-calls (i.e. called
1409+
via a register). */
1410+
1411+
bool
1412+
arc64_is_long_call_p (rtx sym)
1413+
{
1414+
const_tree decl;
1415+
1416+
if (!SYMBOL_REF_P (sym))
1417+
return false;
1418+
1419+
/* If my memory model is small everything can go via usual bl/jl
1420+
instructions. */
1421+
if (arc64_cmodel_var == ARC64_CMODEL_SMALL)
1422+
return false;
1423+
1424+
decl = SYMBOL_REF_DECL (sym);
1425+
if (flag_pic
1426+
&& decl
1427+
&& !targetm.binds_local_p (decl))
1428+
return true;
1429+
1430+
return false;
1431+
}
1432+
13891433
/* X and Y are two things to compare using CODE. Emit the compare insn and
13901434
return the rtx for the cc reg in the proper mode. */
13911435

@@ -1596,8 +1640,8 @@ arc64_expand_call (rtx result, rtx mem, bool sibcall)
15961640
/* Decide if we should generate indirect calls by loading the
15971641
address of the callee into a register before performing the
15981642
branch-and-link. */
1599-
// FIXME! if (arc64_is_long_call_p (callee) && !REG_P (callee))
1600-
// FIXME! XEXP (mem, 0) = force_reg (mode, callee);
1643+
if (arc64_is_long_call_p (callee) && !REG_P (callee))
1644+
XEXP (mem, 0) = force_reg (mode, callee);
16011645

16021646
call = gen_rtx_CALL (VOIDmode, mem, const0_rtx);
16031647

gcc/config/arc64/arc64.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
[
7373
ARC64_UNSPEC_GOTOFF
7474
ARC64_UNSPEC_GOT
75+
ARC64_UNSPEC_GOT32
7576
ARC64_VUNSPEC_BLOCKAGE
7677
])
7778

gcc/config/arc64/arc64.opt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; Machine description for ARC64 architecture.
2+
; Copyright (C) 2019x Free Software Foundation, Inc.
3+
;
4+
; This file is part of GCC.
5+
;
6+
; GCC is free software; you can redistribute it and/or modify it
7+
; under the terms of the GNU General Public License as published by
8+
; the Free Software Foundation; either version 3, or (at your option)
9+
; any later version.
10+
;
11+
; GCC is distributed in the hope that it will be useful, but
12+
; WITHOUT ANY WARRANTY; without even the implied warranty of
13+
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
; General Public License for more details.
15+
;
16+
; You should have received a copy of the GNU General Public License
17+
; along with GCC; see the file COPYING3. If not see
18+
; <http://www.gnu.org/licenses/>.
19+
20+
HeaderInclude
21+
config/arc64/arc64-opts.h
22+
23+
Enum
24+
Name(cmodel) Type(enum arc64_code_model)
25+
The code model option names for -mcmodel:
26+
27+
EnumValue
28+
Enum(cmodel) String(small) Value(ARC64_CMODEL_SMALL)
29+
30+
EnumValue
31+
Enum(cmodel) String(medium) Value(ARC64_CMODEL_MEDIUM)
32+
33+
EnumValue
34+
Enum(cmodel) String(large) Value(ARC64_CMODEL_LARGE)
35+
36+
mcmodel=
37+
Target RejectNegative Joined Enum(cmodel) Var(arc64_cmodel_var) Init(ARC64_CMODEL_MEDIUM) Save
38+
Specify the code model.

gcc/config/arc64/predicates.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141

4242
;; Acceptable arguments for the call insn.
4343
(define_predicate "arc64_call_insn_operand"
44-
(ior (match_code "symbol_ref")
44+
(ior (and (match_code "symbol_ref")
45+
(match_test "!arc64_is_long_call_p (op)"))
4546
(match_operand 0 "register_operand")))
4647

4748
; to be used for br{eq/ne}_s instructions.

0 commit comments

Comments
 (0)