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
e0bfcea5
Commit
e0bfcea5
authored
Apr 08, 1994
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for -membedded-pic
From-SVN: r6997
parent
8926095f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
156 additions
and
12 deletions
+156
-12
gcc/config/mips/mips.c
+31
-0
gcc/config/mips/mips.h
+41
-12
gcc/config/mips/mips.md
+84
-0
No files found.
gcc/config/mips/mips.c
View file @
e0bfcea5
...
...
@@ -3191,6 +3191,28 @@ override_options ()
else
mips_abicalls
=
MIPS_ABICALLS_NO
;
/* -membedded-pic is a form of PIC code suitable for embedded
systems. All calls are made using PC relative addressing, and
all data is addressed using the $gp register. This requires gas,
which does most of the work, and GNU ld, which automatically
expands PC relative calls which are out of range into a longer
instruction sequence. All gcc really does differently is
generate a different sequence for a switch. */
if
(
TARGET_EMBEDDED_PIC
)
{
flag_pic
=
1
;
if
(
TARGET_ABICALLS
)
warning
(
"-membedded-pic and -mabicalls are incompatible"
);
if
(
g_switch_set
)
warning
(
"-G and -membedded-pic are incompatible"
);
/* Setting mips_section_threshold is not required, because gas
will force everything to be GP addressable anyhow, but
setting it will cause gcc to make better estimates of the
number of instructions required to access a particular data
item. */
mips_section_threshold
=
0x7fffffff
;
}
/* -mrnames says to use the MIPS software convention for register
names instead of the hardware names (ie, $a0 instead of $4).
We do this by switching the names in mips_reg_names, which the
...
...
@@ -3387,6 +3409,7 @@ mips_debugger_offset (addr, offset)
'M' print high-order register of double-word register operand.
'C' print part of opcode for a branch condition.
'N' print part of opcode for a branch condition, inverted.
'S' X is CODE_LABEL, print with prefix of "LS" (for embedded switch).
'(' Turn on .set noreorder
')' Turn on .set reorder
'[' Turn on .set noat
...
...
@@ -3569,6 +3592,14 @@ print_operand (file, op, letter)
abort_with_insn
(
op
,
"PRINT_OPERAND, illegal insn for %%N"
);
}
else
if
(
letter
==
'S'
)
{
char
buffer
[
100
];
ASM_GENERATE_INTERNAL_LABEL
(
buffer
,
"LS"
,
CODE_LABEL_NUMBER
(
op
));
assemble_name
(
file
,
buffer
);
}
else
if
(
code
==
REG
)
{
register
int
regnum
=
REGNO
(
op
);
...
...
gcc/config/mips/mips.h
View file @
e0bfcea5
...
...
@@ -254,12 +254,12 @@ extern char *mktemp ();
#define MASK_HALF_PIC 0x00000800
/* Emit OSF-style pic refs to externs*/
#define MASK_LONG_CALLS 0x00001000
/* Always call through a register */
#define MASK_64BIT 0x00002000
/* Use 64 bit GP registers and insns */
#define MASK_
UNUSED1 0x00004000
#define MASK_UNUSED
2
0x00008000
#define MASK_UNUSED
3
0x00010000
#define MASK_UNUSED
4
0x00020000
#define MASK_UNUSED
5
0x00040000
#define MASK_UNUSED
6
0x00080000
#define MASK_
EMBEDDED_PIC 0x00004000
/* Generate embedded PIC code */
#define MASK_UNUSED
1
0x00008000
#define MASK_UNUSED
2
0x00010000
#define MASK_UNUSED
3
0x00020000
#define MASK_UNUSED
4
0x00040000
#define MASK_UNUSED
5
0x00080000
/* Dummy switches used only in spec's*/
#define MASK_MIPS_TFILE 0x00000000
/* flag for mips-tfile usage */
...
...
@@ -327,6 +327,10 @@ extern char *mktemp ();
/* always call through a register */
#define TARGET_LONG_CALLS (target_flags & MASK_LONG_CALLS)
/* generate embedded PIC code;
requires gas. */
#define TARGET_EMBEDDED_PIC (target_flags & MASK_EMBEDDED_PIC)
/* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces,
each pair being { "NAME", VALUE }
...
...
@@ -364,6 +368,8 @@ extern char *mktemp ();
{"no-half-pic", -MASK_HALF_PIC}, \
{"long-calls", MASK_LONG_CALLS}, \
{"no-long-calls", -MASK_LONG_CALLS}, \
{"embedded-pic", MASK_EMBEDDED_PIC}, \
{"no-embedded-pic", -MASK_EMBEDDED_PIC}, \
{"debug", MASK_DEBUG}, \
{"debuga", MASK_DEBUG_A}, \
{"debugb", MASK_DEBUG_B}, \
...
...
@@ -552,7 +558,8 @@ while (0)
%{ggdb:-g} %{ggdb0:-g0} %{ggdb1:-g1} %{ggdb2:-g2} %{ggdb3:-g3} \
%{gstabs:-g} %{gstabs0:-g0} %{gstabs1:-g1} %{gstabs2:-g2} %{gstabs3:-g3} \
%{gstabs+:-g} %{gstabs+0:-g0} %{gstabs+1:-g1} %{gstabs+2:-g2} %{gstabs+3:-g3} \
%{gcoff:-g} %{gcoff0:-g0} %{gcoff1:-g1} %{gcoff2:-g2} %{gcoff3:-g3}"
%{gcoff:-g} %{gcoff0:-g0} %{gcoff1:-g1} %{gcoff2:-g2} %{gcoff3:-g3} \
%{membedded-pic}"
#else
/* not GAS */
...
...
@@ -568,7 +575,8 @@ while (0)
%{ggdb:-g} %{ggdb0:-g0} %{ggdb1:-g1} %{ggdb2:-g2} %{ggdb3:-g3} \
%{gstabs:-g} %{gstabs0:-g0} %{gstabs1:-g1} %{gstabs2:-g2} %{gstabs3:-g3} \
%{gstabs+:-g} %{gstabs+0:-g0} %{gstabs+1:-g1} %{gstabs+2:-g2} %{gstabs+3:-g3} \
%{gcoff:-g} %{gcoff0:-g0} %{gcoff1:-g1} %{gcoff2:-g2} %{gcoff3:-g3}"
%{gcoff:-g} %{gcoff0:-g0} %{gcoff1:-g1} %{gcoff2:-g2} %{gcoff3:-g3} \
%{membedded-pic}"
#endif
#endif
/* ASM_SPEC */
...
...
@@ -3375,12 +3383,33 @@ do { \
VALUE)
/* This is how to output an element of a case-vector that is relative.
This is used for pc-relative code (e.g. when TARGET_ABICALLS). */
This is used for pc-relative code (e.g. when TARGET_ABICALLS or
TARGET_EMBEDDED_PIC). */
#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, VALUE, REL) \
fprintf (STREAM, "\t%s\t$L%d\n", \
TARGET_LONG64 ? ".gpdword" : ".gpword", \
VALUE)
do { \
if (TARGET_EMBEDDED_PIC) \
fprintf (STREAM, "\t%s\t$L%d-$LS%d\n", \
TARGET_LONG64 ? ".dword" : ".word", \
VALUE, REL); \
else \
fprintf (STREAM, "\t%s\t$L%d\n", \
TARGET_LONG64 ? ".gpdword" : ".gpword", \
VALUE); \
} while (0)
/* When generating embedded PIC code we want to put the jump table in
the .text section. In all other cases, we want to put the jump
table in the .rdata section. Unfortunately, we can't use
JUMP_TABLES_IN_TEXT_SECTION, because it is not conditional.
Instead, we use ASM_OUTPUT_CASE_LABEL to switch back to the .text
section if appropriate. */
#define ASM_OUTPUT_CASE_LABEL(FILE, PREFIX, NUM, INSN) \
do { \
if (TARGET_EMBEDDED_PIC) \
text_section (); \
ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM); \
} while (0)
/* This is how to output an assembler line
that says to advance the location counter
...
...
gcc/config/mips/mips.md
View file @
e0bfcea5
...
...
@@ -5410,6 +5410,90 @@ move\\t%0,%z4\\n\\
(set_attr "mode" "none")
(set_attr "length" "1")])
;; Implement a switch statement when generating embedded PIC code.
;; Switches are implemented by
`
tablejump' when not using -membedded-pic.
(define_expand "casesi"
[
(set (match_dup 5)
(minus:SI (match_operand:SI 0 "register_operand" "d")
(match_operand:SI 1 "arith_operand" "dI")))
(set (cc0)
(compare:CC (match_dup 5)
(match_operand:SI 2 "arith_operand" "")))
(set (pc)
(if_then_else (gtu (cc0)
(const_int 0))
(label_ref (match_operand 4 "" ""))
(pc)))
(parallel
[
(set (pc)
(mem:SI (plus:SI (mult:SI (match_dup 5)
(const_int 4))
(label_ref (match_operand 3 "" "")))))
(clobber (match_scratch:SI 6 ""))
(clobber (reg:SI 31))])]
"TARGET_EMBEDDED_PIC"
"
{
/
* We need slightly different code for eight byte table entries. *
/
if (TARGET_LONG64)
abort ();
if (operands
[
0
]
)
{
rtx reg = gen_reg_rtx (SImode);
/* The constraints should handle this, but they don't. */
operands[0] = force_reg (SImode, operands[0]);
if (! arith_operand (operands[1]))
operands[1] = force_reg (SImode, operands[1]);
if (! arith_operand (operands[2]))
operands[2] = force_reg (SImode, operands[2]);
/* If the index is too large, go to the default label. */
emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
emit_insn (gen_cmpsi (reg, operands[2]));
emit_insn (gen_bgtu (operands[4]));
/* Do the PIC jump. */
emit_insn (gen_casesi_internal (reg, operands[3], gen_reg_rtx (SImode)));
DONE;
}
}")
;; An embedded PIC switch statement looks like this:
;; bal $LS1
;; sll $reg,$index,2
;; $LS1:
;; addu $reg,$reg,$31
;; lw $reg,$L1-$LS1($reg)
;; addu $reg,$reg,$31
;; j $reg
;; $L1:
;; .word case1-$LS1
;; .word case2-$LS1
;; ...
(define_insn "casesi_internal"
[
(set (pc)
(mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "d")
(const_int 4))
(label_ref (match_operand 1 "" "")))))
(clobber (match_operand:SI 2 "register_operand" "d"))
(clobber (reg:SI 31))]
"TARGET_EMBEDDED_PIC"
"
*
{
output_asm_insn (
\"
%(bal
\\
t%S1
\;
sll
\\
t%0,2
\\
n%S1:
\"
, operands);
output_asm_insn (
\"
addu
\\
t%0,%0,$31%)
\"
, operands);
output_asm_insn (
\"
lw
\\
t%0,%1-%S1(%0)
\;
addu
\\
t%0,%0,$31
\"
, operands);
return
\"
j
\\
t%0
\"
;
}"
[
(set_attr "type" "jump")
(set_attr "mode" "none")
(set_attr "length" "6")])
;;
;; ....................
...
...
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