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
e1c8bbf4
Commit
e1c8bbf4
authored
Jan 15, 1992
by
Charles Hannum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
entered into RCS
From-SVN: r188
parent
2042e9d2
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
220 additions
and
0 deletions
+220
-0
gcc/config/convex/convex.c
+220
-0
No files found.
gcc/config/convex/convex.c
0 → 100644
View file @
e1c8bbf4
/* Subroutines for insn-output.c for Convex.
Copyright (C) 1989,1991 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "config.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "real.h"
#include "insn-config.h"
#include "conditions.h"
#include "insn-flags.h"
#include "output.h"
#include "insn-attr.h"
/* Boolean to keep track of whether the current section is .text or not.
Used by .align handler in convex.h. */
int
current_section_is_text
;
/* set_cmp saves the operands of a "cmp" insn, along with the type character
* to be used in the compare instruction.
*
* gen_cmp finds out what comparison is to be performed and outputs the
* necessary instructions, e.g.
* "eq.w a1,a2\;jbra.t L5"
* for (cmpsi a1 a2) (beq L5) */
static
rtx
xop0
,
xop1
;
static
char
typech
,
regch
;
char
*
set_cmp
(
op0
,
op1
,
typechr
)
rtx
op0
,
op1
;
char
typechr
;
{
xop0
=
op0
;
xop1
=
op1
;
typech
=
typechr
;
if
(
GET_CODE
(
op0
)
==
REG
)
regch
=
A_REGNO_P
(
REGNO
(
op0
))
?
'a'
:
's'
;
else
if
(
GET_CODE
(
op1
)
==
REG
)
regch
=
A_REGNO_P
(
REGNO
(
op1
))
?
'a'
:
's'
;
else
abort
();
return
""
;
}
char
*
gen_cmp
(
label
,
cmpop
,
tf
)
rtx
label
;
char
*
cmpop
;
char
tf
;
{
char
buf
[
80
];
char
revop
[
4
];
rtx
ops
[
3
];
ops
[
2
]
=
label
;
/* Constant must be first; swap operands if necessary.
If lt, le, ltu, leu are swapped, change to le, lt, leu, ltu
and reverse the sense of the jump. */
if
(
CONSTANT_P
(
xop1
))
{
ops
[
0
]
=
xop1
;
ops
[
1
]
=
xop0
;
if
(
cmpop
[
0
]
==
'l'
)
{
bcopy
(
cmpop
,
revop
,
sizeof
revop
);
revop
[
1
]
^=
'e'
^
't'
;
tf
^=
't'
^
'f'
;
cmpop
=
revop
;
}
}
else
{
ops
[
0
]
=
xop0
;
ops
[
1
]
=
xop1
;
}
sprintf
(
buf
,
"%s.%c %%0,%%1
\n\t
jbr%c.%c %%l2"
,
cmpop
,
typech
,
regch
,
tf
);
output_asm_insn
(
buf
,
ops
);
return
""
;
}
/* Routines to separate CONST_DOUBLEs into component parts. */
int
const_double_high_int
(
x
)
rtx
x
;
{
if
(
GET_MODE_CLASS
(
GET_MODE
(
x
))
==
MODE_FLOAT
)
return
CONST_DOUBLE_LOW
(
x
);
else
return
CONST_DOUBLE_HIGH
(
x
);
}
int
const_double_low_int
(
x
)
rtx
x
;
{
if
(
GET_MODE_CLASS
(
GET_MODE
(
x
))
==
MODE_FLOAT
)
return
CONST_DOUBLE_HIGH
(
x
);
else
return
CONST_DOUBLE_LOW
(
x
);
}
/* Return the number of args in the call insn X. */
static
int
call_num_args
(
x
)
rtx
x
;
{
if
(
GET_CODE
(
x
)
==
CALL
)
return
INTVAL
(
x
->
fld
[
1
].
rtx
);
if
(
GET_CODE
(
x
)
==
SET
)
return
call_num_args
(
SET_SRC
(
x
));
abort
();
}
/* Scan forward from a call to decide whether we need to reload AP
from 12(FP) after it. We need to if there can be a reference to
arg_pointer_rtx before the next call, which will clobber AP.
Look forward in the instruction list until encountering a call
(don't need the load), or a reference to AP (do need it), or
a jump (don't know, do the load). */
static
int
ap_reload_needed
(
insn
)
rtx
insn
;
{
for
(;;)
{
insn
=
NEXT_INSN
(
insn
);
switch
(
GET_CODE
(
insn
))
{
case
JUMP_INSN
:
/* Basic block ends. If return, no AP needed, else assume it is. */
return
GET_CODE
(
PATTERN
(
insn
))
!=
RETURN
;
case
CALL_INSN
:
/* A subsequent call. AP isn't needed unless the call itself
requires it. But zero-arg calls don't clobber AP, so
don't terminate the search in that case. */
if
(
reg_mentioned_p
(
arg_pointer_rtx
,
PATTERN
(
insn
)))
return
1
;
if
(
!
TARGET_ARGCOUNT
&&
call_num_args
(
PATTERN
(
insn
))
==
0
)
break
;
return
0
;
case
BARRIER
:
/* Barrier, don't need AP. */
return
0
;
case
INSN
:
/* Other insn may need AP; if not, keep looking. */
if
(
reg_mentioned_p
(
arg_pointer_rtx
,
PATTERN
(
insn
)))
return
1
;
}
}
}
/* Output the insns needed to do a call. */
char
*
output_call
(
insn
,
address
,
argcount
)
rtx
insn
,
address
,
argcount
;
{
int
set_ap
=
TARGET_ARGCOUNT
||
argcount
!=
const0_rtx
;
/* If AP is used by the call address, evaluate the address into a temp. */
if
(
reg_mentioned_p
(
arg_pointer_rtx
,
address
))
if
(
set_ap
)
{
address
=
XEXP
(
address
,
0
);
output_asm_insn
(
"ld.w %0,a1"
,
&
address
);
address
=
gen_rtx
(
MEM
,
QImode
,
gen_rtx
(
REG
,
Pmode
,
9
));
}
/* If there are args, point AP to them. */
if
(
set_ap
)
output_asm_insn
(
"mov sp,ap"
);
/* If we are passing an arg count, convert it to words and push it. */
if
(
TARGET_ARGCOUNT
)
{
argcount
=
gen_rtx
(
CONST_INT
,
VOIDmode
,
(
INTVAL
(
argcount
)
+
3
)
/
4
);
output_asm_insn
(
"pshea %a0"
,
&
argcount
);
}
/* The call. */
output_asm_insn
(
"calls %0"
,
&
address
);
/* If we clobbered AP, reload it if it is live. */
if
(
set_ap
)
if
(
ap_reload_needed
(
insn
))
output_asm_insn
(
"ld.w 12(fp),ap"
);
/* If we pushed an arg count, pop it and the args. */
if
(
TARGET_ARGCOUNT
)
{
argcount
=
gen_rtx
(
CONST_INT
,
VOIDmode
,
INTVAL
(
argcount
)
*
4
+
4
);
output_asm_insn
(
"add.w %0,sp"
,
&
argcount
);
}
return
""
;
}
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