Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
766a866c
Commit
766a866c
authored
Apr 08, 1996
by
Michael Meissner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add -fpic/-fPIC support
From-SVN: r11676
parent
2038dc12
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
148 additions
and
3 deletions
+148
-3
gcc/config/rs6000/rs6000.c
+16
-0
gcc/config/rs6000/rs6000.h
+52
-1
gcc/config/rs6000/rs6000.md
+80
-2
No files found.
gcc/config/rs6000/rs6000.c
View file @
766a866c
...
@@ -93,6 +93,9 @@ enum rs6000_abi rs6000_current_abi;
...
@@ -93,6 +93,9 @@ enum rs6000_abi rs6000_current_abi;
/* Temporary memory used to convert integer -> float */
/* Temporary memory used to convert integer -> float */
static
rtx
stack_temps
[
NUM_MACHINE_MODES
];
static
rtx
stack_temps
[
NUM_MACHINE_MODES
];
/* Current PIC register used by the V4 code */
struct
rtx_def
*
rs6000_pic_register
=
(
struct
rtx_def
*
)
0
;
/* Print the options used in the assembly file. */
/* Print the options used in the assembly file. */
...
@@ -524,6 +527,18 @@ reg_or_cint_operand (op, mode)
...
@@ -524,6 +527,18 @@ reg_or_cint_operand (op, mode)
return
GET_CODE
(
op
)
==
CONST_INT
||
gpc_reg_operand
(
op
,
mode
);
return
GET_CODE
(
op
)
==
CONST_INT
||
gpc_reg_operand
(
op
,
mode
);
}
}
/* Return 1 if the operand is an operand that can be loaded via the GOT */
int
got_operand
(
op
,
mode
)
register
rtx
op
;
enum
machine_mode
mode
;
{
return
(
GET_CODE
(
op
)
==
SYMBOL_REF
||
GET_CODE
(
op
)
==
CONST
||
GET_CODE
(
op
)
==
LABEL_REF
);
}
/* Return the number of instructions it takes to form a constant in an
/* Return the number of instructions it takes to form a constant in an
integer register. */
integer register. */
...
@@ -3663,6 +3678,7 @@ output_epilog (file, size)
...
@@ -3663,6 +3678,7 @@ output_epilog (file, size)
/* Reset varargs and save TOC indicator */
/* Reset varargs and save TOC indicator */
rs6000_sysv_varargs_p
=
0
;
rs6000_sysv_varargs_p
=
0
;
rs6000_save_toc_p
=
0
;
rs6000_save_toc_p
=
0
;
rs6000_pic_register
=
(
rtx
)
0
;
if
(
DEFAULT_ABI
==
ABI_NT
)
if
(
DEFAULT_ABI
==
ABI_NT
)
{
{
...
...
gcc/config/rs6000/rs6000.h
View file @
766a866c
...
@@ -1842,6 +1842,54 @@ typedef struct rs6000_args
...
@@ -1842,6 +1842,54 @@ typedef struct rs6000_args
goto LABEL; \
goto LABEL; \
}
}
/* The register number of the register used to address a table of
static data addresses in memory. In some cases this register is
defined by a processor's "application binary interface" (ABI).
When this macro is defined, RTL is generated for this register
once, as with the stack pointer and frame pointer registers. If
this macro is not defined, it is up to the machine-dependent files
to allocate such a register (if necessary). */
/* #define PIC_OFFSET_TABLE_REGNUM */
/* Define this macro if the register defined by
`PIC_OFFSET_TABLE_REGNUM' is clobbered by calls. Do not define
this macro if `PPIC_OFFSET_TABLE_REGNUM' is not defined. */
/* #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED */
/* By generating position-independent code, when two different
programs (A and B) share a common library (libC.a), the text of
the library can be shared whether or not the library is linked at
the same address for both programs. In some of these
environments, position-independent code requires not only the use
of different addressing modes, but also special code to enable the
use of these addressing modes.
The `FINALIZE_PIC' macro serves as a hook to emit these special
codes once the function is being compiled into assembly code, but
not before. (It is not done before, because in the case of
compiling an inline function, it would lead to multiple PIC
prologues being included in functions which used inline functions
and were compiled to assembly language.) */
/* #define FINALIZE_PIC */
/* Current PIC register used by the V4 code */
extern
struct
rtx_def
*
rs6000_pic_register
;
/* A C expression that is nonzero if X is a legitimate immediate
operand on the target machine when generating position independent
code. You can assume that X satisfies `CONSTANT_P', so you need
not check this. You can also assume FLAG_PIC is true, so you need
not check it either. You need not define this macro if all
constants (including `SYMBOL_REF') can be immediate operands when
generating position independent code. */
/* #define LEGITIMATE_PIC_OPERAND_P (X) */
/* Define this if some processing needs to be done immediately before
/* Define this if some processing needs to be done immediately before
emitting code for an insn. */
emitting code for an insn. */
...
@@ -2769,6 +2817,7 @@ do { \
...
@@ -2769,6 +2817,7 @@ do { \
{"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_neg_short_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_u_short_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
{"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \
{"got_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{"easy_fp_constant", {CONST_DOUBLE}}, \
{"easy_fp_constant", {CONST_DOUBLE}}, \
{"reg_or_mem_operand", {SUBREG, MEM, REG}}, \
{"reg_or_mem_operand", {SUBREG, MEM, REG}}, \
{"lwa_operand", {SUBREG, MEM, REG}}, \
{"lwa_operand", {SUBREG, MEM, REG}}, \
...
@@ -2804,7 +2853,8 @@ do { \
...
@@ -2804,7 +2853,8 @@ do { \
(no need to use the default) */
(no need to use the default) */
#define MACHINE_issue_rate
#define MACHINE_issue_rate
/* General optimization flags. */
/* General flags. */
extern
int
flag_pic
;
extern
int
optimize
;
extern
int
optimize
;
extern
int
flag_expensive_optimizations
;
extern
int
flag_expensive_optimizations
;
...
@@ -2824,6 +2874,7 @@ extern int reg_or_short_operand ();
...
@@ -2824,6 +2874,7 @@ extern int reg_or_short_operand ();
extern
int
reg_or_neg_short_operand
();
extern
int
reg_or_neg_short_operand
();
extern
int
reg_or_u_short_operand
();
extern
int
reg_or_u_short_operand
();
extern
int
reg_or_cint_operand
();
extern
int
reg_or_cint_operand
();
extern
int
got_operand
();
extern
int
num_insns_constant
();
extern
int
num_insns_constant
();
extern
int
easy_fp_constant
();
extern
int
easy_fp_constant
();
extern
int
volatile_mem_operand
();
extern
int
volatile_mem_operand
();
...
...
gcc/config/rs6000/rs6000.md
View file @
766a866c
...
@@ -4815,6 +4815,68 @@
...
@@ -4815,6 +4815,68 @@
"TARGET_ELF && !TARGET_64BIT"
"TARGET_ELF && !TARGET_64BIT"
"{cal %0,%a2@l(%1)|addi %0,%1,%2@l}")
"{cal %0,%a2@l(%1)|addi %0,%1,%2@l}")
;; Set up a register with a value from the GOT table
(define_expand "movsi_got"
[
(set (match_operand:SI 0 "register_operand" "")
(unspec
[
(match_operand:SI 1 "got_operand" "")
(match_dup 2)] 8))]
"DEFAULT_ABI == ABI_V4 && flag_pic"
"
{
if (!rs6000_pic_register)
{
rs6000_pic_register = gen_reg_rtx (SImode);
emit_insn (gen_init_v4_pic (rs6000_pic_register));
}
operands
[
2
]
= rs6000_pic_register;
if (flag_pic > 1)
{
emit_insn (gen_movsi_got_large (operands
[
0
]
, operands
[
1
]
, operands
[
2
]
));
DONE;
}
}")
(define_insn "
*
movsi_got_internal1"
[
(set (match_operand:SI 0 "register_operand" "=r")
(unspec
[
(match_operand:SI 1 "got_operand" "")
(match_operand:SI 2 "register_operand" "b")] 8))]
"DEFAULT_ABI == ABI_V4 && flag_pic == 1"
"{l|lwz} %0,%a1@got(%2)"
[
(set_attr "type" "load")
]
)
(define_expand "movsi_got_large"
[
(set (match_dup 3)
(unspec
[
(match_operand:SI 1 "got_operand" "")
]
9))
(set (match_dup 3)
(unspec
[
(match_dup 1)
(match_dup 3)] 10))
(set (match_operand:SI 0 "register_operand" "")
(mem:SI (plus:SI (match_dup 3)
(match_operand:SI 2 "register_operand" ""))))]
"DEFAULT_ABI == ABI_V4 && flag_pic > 1"
"
{
if (reload_completed || reload_in_progress)
abort ();
operands
[
3
]
= gen_reg_rtx (SImode);
}")
(define_insn "
*
movsi_got_internal2_high"
[
(set (match_operand:SI 0 "register_operand" "=b")
(unspec
[
(match_operand:SI 1 "got_operand" "")
]
9))]
"DEFAULT_ABI == ABI_V4 && flag_pic > 1"
"{cau|addis} %0,0,%1@got@ha")
(define_insn "
*
movsi_got_internal2_losum"
[
(set (match_operand:SI 0 "register_operand" "=r")
(unspec
[
(match_operand:SI 1 "got_operand" "")
(match_operand:SI 2 "register_operand" "b")] 10))]
"DEFAULT_ABI == ABI_V4 && flag_pic > 1"
"{cal %0,%a1@got@l(%2)|addi %0,%2,%a1@got@l}")
;; For SI, we special-case integers that can't be loaded in one insn. We
;; For SI, we special-case integers that can't be loaded in one insn. We
;; do the load 16-bits at a time. We could do this by loading from memory,
;; do the load 16-bits at a time. We could do this by loading from memory,
;; and this is even supposed to be faster, but it is simpler not to get
;; and this is even supposed to be faster, but it is simpler not to get
...
@@ -4842,6 +4904,12 @@
...
@@ -4842,6 +4904,12 @@
DONE;
DONE;
}
}
if (DEFAULT_ABI == ABI_V4 && flag_pic && got_operand (operands
[
1
]
, SImode))
{
emit_insn (gen_movsi_got (operands
[
0
]
, operands
[
1
]
));
DONE;
}
if (TARGET_ELF && TARGET_NO_TOC && !TARGET_64BIT
if (TARGET_ELF && TARGET_NO_TOC && !TARGET_64BIT
&& CONSTANT_P (operands
[
1
]
)
&& CONSTANT_P (operands
[
1
]
)
&& GET_CODE (operands
[
1
]
) != HIGH
&& GET_CODE (operands
[
1
]
) != HIGH
...
@@ -6985,7 +7053,7 @@
...
@@ -6985,7 +7053,7 @@
else if (INTVAL (operands
[
2
]
) & CALL_V4_CLEAR_FP_ARGS)
else if (INTVAL (operands
[
2
]
) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (
\"
creqv 6,6,6
\"
, operands);
output_asm_insn (
\"
creqv 6,6,6
\"
, operands);
return
\"
bl %z0
\"
;
return
(flag_pic) ?
\"
bl %z0@plt
\"
:
\"
bl %z0
\"
;
}"
}"
[
(set_attr "type" "branch")
[
(set_attr "type" "branch")
(set_attr "length" "4,8")])
(set_attr "length" "4,8")])
...
@@ -7055,7 +7123,7 @@
...
@@ -7055,7 +7123,7 @@
else if (INTVAL (operands
[
3
]
) & CALL_V4_CLEAR_FP_ARGS)
else if (INTVAL (operands
[
3
]
) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (
\"
creqv 6,6,6
\"
, operands);
output_asm_insn (
\"
creqv 6,6,6
\"
, operands);
return
\"
bl %z1
\"
;
return
(flag_pic) ?
\"
bl %z1@plt
\"
:
\"
bl %z1
\"
;
}"
}"
[
(set_attr "type" "branch")
[
(set_attr "type" "branch")
(set_attr "length" "4,8")])
(set_attr "length" "4,8")])
...
@@ -7123,6 +7191,16 @@
...
@@ -7123,6 +7191,16 @@
""
""
"{ics|isync}")
"{ics|isync}")
;; V.4 specific code to initialize the PIC register
(define_insn "init_v4_pic"
[
(set (match_operand:SI 0 "register_operand" "=l")
(unspec
[
(const_int 0)
]
7))]
"DEFAULT_ABI == ABI_V4"
"bl _GLOBAL_OFFSET_TABLE_-4"
[
(set_attr "type" "branch")
]
)
;; Compare insns are next. Note that the RS/6000 has two types of compares,
;; Compare insns are next. Note that the RS/6000 has two types of compares,
;; signed & unsigned, and one type of branch.
;; signed & unsigned, and one type of branch.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment