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
30102605
Commit
30102605
authored
Sep 11, 2001
by
Richard Henderson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cray T3E port.
From-SVN: r45539
parent
b1c4394d
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
3112 additions
and
223 deletions
+3112
-223
gcc/ChangeLog
+90
-0
gcc/config.gcc
+8
-0
gcc/config/alpha/alpha-protos.h
+21
-0
gcc/config/alpha/alpha.c
+1422
-75
gcc/config/alpha/alpha.h
+14
-3
gcc/config/alpha/alpha.md
+818
-141
gcc/config/alpha/t-unicosmk
+2
-0
gcc/config/alpha/unicosmk.h
+667
-0
gcc/fixinc/fixincl.x
+47
-4
gcc/fixinc/inclhack.def
+17
-0
gcc/ginclude/stddef.h
+6
-0
No files found.
gcc/ChangeLog
View file @
30102605
2001
-
09
-
11
Richard
Henderson
<
rth
@redhat
.
com
>
*
config
/
alpha
/
alpha
.
c
:
Tidy
formatting
.
(
local_symbolic_operand
)
:
Verify
mode
.
(
alpha_sa_mask
)
:
Ignore
unicos
for
eh_return
.
(
alpha_expand_epilogue
)
:
Handle
sp_adj2
zero
,
not
NULL
.
*
config
/
alpha
/
alpha
.
md
(
umk
divsi
patterns
)
:
Remove
.
(
extendsfdf2
)
:
Remove
unicos
check
.
(
tablejump
)
:
Merge
vms
and
unicos
code
;
always
use
direct
set
plus
label_ref
use
.
2001
-
09
-
11
Roman
Lechtchinsky
<
rl
@cs
.
tu
-
berlin
.
de
>
*
config
.
gcc
(
alpha
*-*-
unicosmk
*
)
:
New
target
.
*
config
/
alpha
/
alpha
-
protos
.
h
(
symbolic_operand
,
unicosmk_add_call_info_word
,
unicosmk_add_extern
,
unicosmk_defer_case_vector
,
unicosmk_unique_section
,
unicosmk_output_align
,
unicosmk_text_section
,
unicosmk_data_section
,
unicosmk_asm_file_start
,
unicosmk_asm_file_end
,
unicosmk_output_common
)
:
Declare
.
*
config
/
alpha
/
alpha
.
c
(
NUM_ARGS
,
override_options
,
call_operand
,
direct_return
,
function_arg
,
alpha_va_start
,
alpha_va_arg
,
alpha_does_function_need_gp
,
alpha_end_function
)
:
Support
Cray
Unicos
/
Mk
.
(
alpha_init_machine_status
,
alpha_mark_machine_status
,
alpha_free_machine_status
,
unicosmk_output_deferred_case_vectors
,
unicosmk_gen_dsib
,
unicosmk_output_ssib
,
unicosmk_need_dex
,
unicosmk_asm_named_section
,
unicosmk_insert_attributes
,
unicosmk_section_type_flags
,
symbolic_operand
,
unicosmk_output_module_name
,
unicosmk_output_default_externs
,
unicosmk_output_dex
,
unicosmk_output_externs
,
unicosmk_output_addr_vec
,
unicosmk_ssib_name
,
unicosmk_initial_elimination_offset
,
unicosmk_asm_file_start
,
unicosmk_asm_file_end
,
unicosmk_output_common
,
unicosmk_section_type_flags
,
unicosmk_unique_section
,
unicosmk_add_call_info_word
,
unicosmk_text_section
,
unicosmk_data_section
,
unicosmk_extern_list
,
unicosmk_extern_head
,
unicosmk_add_extern
,
unicosmk_dex
,
unicosmk_dex_list
,
unicosmk_dex_count
,
unicosmk_special_name
)
:
New
.
(
TARGET_INSERT_ATTRIBUTES
,
TARGET_SECTION_TYPE_FLAGS
)
:
Define
for
TARGET_ABI_UNICOSMK
.
(
get_aligned_mem
,
alpha_expand_unaligned_load
,
alpha_expand_unaligned_store
,
alpha_expand_unaligned_load_words
,
alpha_expand_unaligned_store_words
)
:
Support
big
-
endian
mode
.
(
print_operand
)
:
Likewise
.
New
format
specifier
't'
.
Use
TARGET_AS_SLASH_BEFORE_SUFFIX
.
(
alpha_is_stack_procedure
)
:
Rename
from
vms_is_stack_procedure
.
(
alpha_pv_save_size
)
:
Update
with
above
change
.
(
alpha_sa_mask
,
alpha_sa_size
,
alpha_expand_prologue
,
alpha_start_function
,
alpha_expand_epilogue
)
:
Likewise
.
Support
Cray
Unicos
/
Mk
.
*
config
/
alpha
/
alpha
.
h
(
TARGET_ABI_UNICOSMK
)
:
New
.
(
TARGET_ABI_OSF
)
:
Exclude
TARGET_ABI_UNICOSMK
.
(
TARGET_AS_SLASH_BEFORE_SUFFIX
)
:
New
.
(
EXTRA_CONSTRAINT
)
:
New
constraint
'U'
.
(
PREDICATE_CODES
)
:
Add
symbolic_operand
.
*
config
/
alpha
/
alpha
.
md
(
UNSPEC_UMK_LAUM
,
UNSPEC_UMK_LALM
,
UNSPEC_UMK_LAL
,
UNSPEC_UMK_LOAD_CIW
)
:
New
constants
.
(
mulsi3
,
*
mulsi_se
,
mulvsi3
)
:
Disable
for
TARGET_ABI_UNICOSMK
.
(
integer
division
and
modulus
patterns
)
:
Split
in
default
and
Unicos
/
Mk
versions
.
(
*
divmodsi_internal
,
*
divmoddi_internal
)
:
Disable
for
TARGET_ABI_UNICOSMK
.
(
unaligned_extend
?
idi
,
unaligned_load
?
i
,
unaligned_store
?
i
):
Split
in
little
-
endian
and
big
-
endian
versions
.
(
ext
,
ins
,
msk
):
Likewise
.
(
extv
,
extzv
,
insv
):
Support
big
-
endian
mode
.
(
call
,
call_value
,
tablejump
)
:
Support
TARGET_ABI_UNICOSMK
.
(
call_umk
,
call_value_umk
,
*
call_umk
,
tablejump_umk
,
*
tablejump_umk_internal
,
*
call_value_umk
)
:
New
.
(
*
movdi_nofix
)
:
Add
pattern
for
loading
an
address
into
a
register
on
TARGET_ABI_UNICOSMK
.
(
umk_laum
,
umk_lal
,
umk_lalm
,
*
umk_load_ciw
)
:
New
.
(
umk_mismatch_args
,
arg_home_umk
)
:
New
.
(
various
insns
)
:
Don
'
t
use
mov
,
fmov
,
nop
,
fnop
and
unop
.
(
realign
)
:
Support
TARGET_ABI_UNICOSMK
.
*
config
/
alpha
/
unicosmk
.
h
:
New
file
.
*
config
/
alpha
/
t
-
unicosmk
:
New
file
.
*
fixinc
/
inclhack
.
def
(
unicosmk_restrict
)
:
New
.
*
fixinc
/
fixincl
.
x
:
Regenerate
.
*
ginclude
/
stddef
.
h
(
size_t
)
:
Check
for
and
define
__SIZE_T__
.
(
wchar_t
)
:
Check
for
and
define
__WCHAR_T__
.
2001
-
09
-
11
Richard
Sandiford
<
rsandifo
@redhat
.
com
>
*
combine
.
c
(
simplify_shift_const
)
:
Treat
shifts
by
the
mode
...
...
gcc/config.gcc
View file @
30102605
...
...
@@ -398,6 +398,14 @@ a29k-wrs-vxworks*)
a29k-*-*) # Default a29k environment.
use_collect2=yes
;;
alpha*-*-unicosmk*)
use_collect2=yes
tm_file="${tm_file} alpha/unicosmk.h"
# Don't include t-ieee for now because we don't support that yet
# tmake_file="alpha/t-ieee"
tmake_file="alpha/t-unicosmk"
;;
alpha-*-interix)
tm_file="${tm_file} alpha/alpha32.h interix.h alpha/alpha-interix.h"
...
...
gcc/config/alpha/alpha-protos.h
View file @
30102605
...
...
@@ -56,6 +56,7 @@ extern int input_operand PARAMS ((rtx, enum machine_mode));
extern
int
current_file_function_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
local_symbolic_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
call_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
symbolic_operand
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
alpha_comparison_operator
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
alpha_zero_comparison_operator
PARAMS
((
rtx
,
enum
machine_mode
));
extern
int
alpha_swapped_comparison_operator
PARAMS
((
rtx
,
enum
machine_mode
));
...
...
@@ -149,3 +150,23 @@ extern void alpha_start_function PARAMS ((FILE *, const char *, tree));
extern
void
alpha_end_function
PARAMS
((
FILE
*
,
const
char
*
,
tree
));
extern
void
alpha_encode_section_info
PARAMS
((
tree
));
#endif
/* TREE CODE */
#ifdef RTX_CODE
extern
rtx
unicosmk_add_call_info_word
PARAMS
((
rtx
));
#endif
#if TARGET_ABI_UNICOSMK
#ifdef RTX_CODE
extern
void
unicosmk_defer_case_vector
PARAMS
((
rtx
,
rtx
));
#endif
#ifdef TREE_CODE
extern
void
unicosmk_unique_section
PARAMS
((
tree
,
int
));
#endif
extern
void
unicosmk_add_extern
PARAMS
((
const
char
*
));
extern
void
unicosmk_output_align
PARAMS
((
FILE
*
,
int
));
extern
char
*
unicosmk_text_section
PARAMS
((
void
));
extern
char
*
unicosmk_data_section
PARAMS
((
void
));
extern
void
unicosmk_asm_file_start
PARAMS
((
FILE
*
));
extern
void
unicosmk_asm_file_end
PARAMS
((
FILE
*
));
extern
void
unicosmk_output_common
PARAMS
((
FILE
*
,
const
char
*
,
int
,
int
));
#endif
/* TARGET_ABI_UNICOSMK */
gcc/config/alpha/alpha.c
View file @
30102605
...
...
@@ -153,8 +153,22 @@ static int alpha_issue_rate
static
int
alpha_variable_issue
PARAMS
((
FILE
*
,
int
,
rtx
,
int
));
#if TARGET_ABI_UNICOSMK
static
void
alpha_init_machine_status
PARAMS
((
struct
function
*
p
));
static
void
alpha_mark_machine_status
PARAMS
((
struct
function
*
p
));
static
void
alpha_free_machine_status
PARAMS
((
struct
function
*
p
));
#endif
static
void
unicosmk_output_deferred_case_vectors
PARAMS
((
FILE
*
));
static
void
unicosmk_gen_dsib
PARAMS
((
unsigned
long
*
imaskP
));
static
void
unicosmk_output_ssib
PARAMS
((
FILE
*
,
const
char
*
));
static
int
unicosmk_need_dex
PARAMS
((
rtx
));
/* Get the number of args of a function in one of two ways. */
#if TARGET_ABI_OPEN_VMS
#if TARGET_ABI_OPEN_VMS
|| TARGET_ABI_UNICOSMK
#define NUM_ARGS current_function_args_info.num_args
#else
#define NUM_ARGS current_function_args_info
...
...
@@ -176,6 +190,17 @@ static void vms_asm_out_destructor PARAMS ((rtx, int));
# define TARGET_SECTION_TYPE_FLAGS vms_section_type_flags
#endif
#if TARGET_ABI_UNICOSMK
static
void
unicosmk_asm_named_section
PARAMS
((
const
char
*
,
unsigned
int
));
static
void
unicosmk_insert_attributes
PARAMS
((
tree
,
tree
*
));
static
unsigned
int
unicosmk_section_type_flags
PARAMS
((
tree
,
const
char
*
,
int
));
# undef TARGET_INSERT_ATTRIBUTES
# define TARGET_INSERT_ATTRIBUTES unicosmk_insert_attributes
# undef TARGET_SECTION_TYPE_FLAGS
# define TARGET_SECTION_TYPE_FLAGS unicosmk_section_type_flags
#endif
#undef TARGET_ASM_FUNCTION_END_PROLOGUE
#define TARGET_ASM_FUNCTION_END_PROLOGUE alpha_output_function_end_prologue
...
...
@@ -218,21 +243,51 @@ override_options ()
{
0
,
0
,
0
}
};
alpha_tp
=
ALPHA_TP_PROG
;
/* Unicos/Mk doesn't have shared libraries. */
if
(
TARGET_ABI_UNICOSMK
&&
flag_pic
)
{
warning
(
"-f%s ignored for Unicos/Mk (not supported)"
,
(
flag_pic
>
1
)
?
"PIC"
:
"pic"
);
flag_pic
=
0
;
}
/* On Unicos/Mk, the native compiler consistenly generates /d suffices for
floating-point instructions. Make that the default for this target. */
if
(
TARGET_ABI_UNICOSMK
)
alpha_fprm
=
ALPHA_FPRM_DYN
;
else
alpha_fprm
=
ALPHA_FPRM_NORM
;
alpha_tp
=
ALPHA_TP_PROG
;
alpha_fptm
=
ALPHA_FPTM_N
;
/* We cannot use su and sui qualifiers for conversion instructions on
Unicos/Mk. I'm not sure if this is due to assembler or hardware
limitations. Right now, we issue a warning if -mieee is specified
and then ignore it; eventually, we should either get it right or
disable the option altogether. */
if
(
TARGET_IEEE
)
{
if
(
TARGET_ABI_UNICOSMK
)
warning
(
"-mieee not supported on Unicos/Mk"
);
else
{
alpha_tp
=
ALPHA_TP_INSN
;
alpha_fptm
=
ALPHA_FPTM_SU
;
}
}
if
(
TARGET_IEEE_WITH_INEXACT
)
{
if
(
TARGET_ABI_UNICOSMK
)
warning
(
"-mieee-with-inexact not supported on Unicos/Mk"
);
else
{
alpha_tp
=
ALPHA_TP_INSN
;
alpha_fptm
=
ALPHA_FPTM_SUI
;
}
}
if
(
alpha_tp_string
)
{
...
...
@@ -308,6 +363,12 @@ override_options ()
/* Do some sanity checks on the above options. */
if
(
TARGET_ABI_UNICOSMK
&&
alpha_fptm
!=
ALPHA_FPTM_N
)
{
warning
(
"trap mode not supported on Unicos/Mk"
);
alpha_fptm
=
ALPHA_FPTM_N
;
}
if
((
alpha_fptm
==
ALPHA_FPTM_SU
||
alpha_fptm
==
ALPHA_FPTM_SUI
)
&&
alpha_tp
!=
ALPHA_TP_INSN
&&
!
TARGET_CPU_EV6
)
{
...
...
@@ -402,6 +463,15 @@ override_options ()
/* Acquire a unique set number for our register saves and restores. */
alpha_sr_alias_set
=
new_alias_set
();
/* Register variables and functions with the garbage collector. */
#if TARGET_ABI_UNICOSMK
/* Set up function hooks. */
init_machine_status
=
alpha_init_machine_status
;
mark_machine_status
=
alpha_mark_machine_status
;
free_machine_status
=
alpha_free_machine_status
;
#endif
}
/* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */
...
...
@@ -774,10 +844,13 @@ current_file_function_operand (op, mode)
int
local_symbolic_operand
(
op
,
mode
)
rtx
op
;
enum
machine_mode
mode
ATTRIBUTE_UNUSED
;
enum
machine_mode
mode
;
{
const
char
*
str
;
if
(
mode
!=
VOIDmode
&&
GET_MODE
(
op
)
!=
VOIDmode
&&
mode
!=
GET_MODE
(
op
))
return
0
;
if
(
GET_CODE
(
op
)
==
LABEL_REF
)
return
1
;
...
...
@@ -813,6 +886,8 @@ call_operand (op, mode)
if
(
mode
!=
Pmode
)
return
0
;
if
(
TARGET_ABI_UNICOSMK
)
return
GET_CODE
(
op
)
==
REG
;
if
(
GET_CODE
(
op
)
==
SYMBOL_REF
)
return
1
;
if
(
GET_CODE
(
op
)
==
REG
)
...
...
@@ -826,6 +901,26 @@ call_operand (op, mode)
return
0
;
}
/* Returns 1 if OP is a symbolic operand, i.e. a symbol_ref or a label_ref,
possibly with an offset. */
int
symbolic_operand
(
op
,
mode
)
register
rtx
op
;
enum
machine_mode
mode
;
{
if
(
mode
!=
VOIDmode
&&
GET_MODE
(
op
)
!=
VOIDmode
&&
mode
!=
GET_MODE
(
op
))
return
0
;
if
(
GET_CODE
(
op
)
==
SYMBOL_REF
||
GET_CODE
(
op
)
==
LABEL_REF
)
return
1
;
if
(
GET_CODE
(
op
)
==
CONST
&&
GET_CODE
(
XEXP
(
op
,
0
))
==
PLUS
&&
GET_CODE
(
XEXP
(
XEXP
(
op
,
0
),
0
))
==
SYMBOL_REF
&&
GET_CODE
(
XEXP
(
XEXP
(
op
,
0
),
1
))
==
CONST_INT
)
return
1
;
return
0
;
}
/* Return 1 if OP is a valid Alpha comparison operator. Here we know which
comparisons are valid in which insn. */
...
...
@@ -1140,7 +1235,7 @@ addition_operation (op, mode)
int
direct_return
()
{
return
(
!
TARGET_ABI_OPEN_VMS
return
(
!
TARGET_ABI_OPEN_VMS
&&
!
TARGET_ABI_UNICOSMK
&&
reload_completed
&&
alpha_sa_size
()
==
0
&&
get_frame_size
()
==
0
...
...
@@ -1582,6 +1677,10 @@ get_aligned_mem (ref, paligned_mem, pbitnum)
data in a different alias set. */
set_mem_alias_set
(
*
paligned_mem
,
0
);
if
(
WORDS_BIG_ENDIAN
)
*
pbitnum
=
GEN_INT
(
32
-
(
GET_MODE_BITSIZE
(
GET_MODE
(
ref
))
+
(
offset
&
3
)
*
8
));
else
*
pbitnum
=
GEN_INT
((
offset
&
3
)
*
8
);
}
...
...
@@ -3197,12 +3296,23 @@ alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
set_mem_alias_set
(
tmp
,
0
);
emit_move_insn
(
memh
,
tmp
);
if
(
sign
&&
size
==
2
)
if
(
WORDS_BIG_ENDIAN
&&
sign
&&
(
size
==
2
||
size
==
4
))
{
emit_move_insn
(
addr
,
plus_constant
(
mema
,
-
1
));
emit_insn
(
gen_extqh_be
(
extl
,
meml
,
addr
));
emit_insn
(
gen_extxl_be
(
exth
,
memh
,
GEN_INT
(
64
),
addr
));
addr
=
expand_binop
(
DImode
,
ior_optab
,
extl
,
exth
,
tgt
,
1
,
OPTAB_WIDEN
);
addr
=
expand_binop
(
DImode
,
ashr_optab
,
addr
,
GEN_INT
(
64
-
size
*
8
),
addr
,
1
,
OPTAB_WIDEN
);
}
else
if
(
sign
&&
size
==
2
)
{
emit_move_insn
(
addr
,
plus_constant
(
mema
,
ofs
+
2
));
emit_insn
(
gen_extxl
(
extl
,
meml
,
GEN_INT
(
64
),
addr
));
emit_insn
(
gen_extqh
(
exth
,
memh
,
addr
));
emit_insn
(
gen_extxl
_le
(
extl
,
meml
,
GEN_INT
(
64
),
addr
));
emit_insn
(
gen_extqh
_le
(
exth
,
memh
,
addr
));
/* We must use tgt here for the target. Alpha-vms port fails if we use
addr for the target, because addr is marked as a pointer and combine
...
...
@@ -3213,28 +3323,56 @@ alpha_expand_unaligned_load (tgt, mem, size, ofs, sign)
}
else
{
if
(
WORDS_BIG_ENDIAN
)
{
emit_move_insn
(
addr
,
plus_constant
(
mema
,
ofs
+
size
-
1
));
switch
((
int
)
size
)
{
case
2
:
emit_insn
(
gen_extwh_be
(
extl
,
meml
,
addr
));
mode
=
HImode
;
break
;
case
4
:
emit_insn
(
gen_extlh_be
(
extl
,
meml
,
addr
));
mode
=
SImode
;
break
;
case
8
:
emit_insn
(
gen_extqh_be
(
extl
,
meml
,
addr
));
mode
=
DImode
;
break
;
default
:
abort
();
}
emit_insn
(
gen_extxl_be
(
exth
,
memh
,
GEN_INT
(
size
*
8
),
addr
));
}
else
{
emit_move_insn
(
addr
,
plus_constant
(
mema
,
ofs
));
emit_insn
(
gen_extxl
(
extl
,
meml
,
GEN_INT
(
size
*
8
),
addr
));
emit_insn
(
gen_extxl_le
(
extl
,
meml
,
GEN_INT
(
size
*
8
),
addr
));
switch
((
int
)
size
)
{
case
2
:
emit_insn
(
gen_extwh
(
exth
,
memh
,
addr
));
emit_insn
(
gen_extwh_le
(
exth
,
memh
,
addr
));
mode
=
HImode
;
break
;
case
4
:
emit_insn
(
gen_extlh
(
exth
,
memh
,
addr
));
emit_insn
(
gen_extlh_le
(
exth
,
memh
,
addr
));
mode
=
SImode
;
break
;
case
8
:
emit_insn
(
gen_extqh
(
exth
,
memh
,
addr
));
emit_insn
(
gen_extqh_le
(
exth
,
memh
,
addr
));
mode
=
DImode
;
break
;
default
:
abort
();
}
}
addr
=
expand_binop
(
mode
,
ior_optab
,
gen_lowpart
(
mode
,
extl
),
gen_lowpart
(
mode
,
exth
),
gen_lowpart
(
mode
,
tgt
),
...
...
@@ -3281,6 +3419,52 @@ alpha_expand_unaligned_store (dst, src, size, ofs)
emit_move_insn
(
dsth
,
memh
);
emit_move_insn
(
dstl
,
meml
);
if
(
WORDS_BIG_ENDIAN
)
{
addr
=
copy_addr_to_reg
(
plus_constant
(
dsta
,
ofs
+
size
-
1
));
if
(
src
!=
const0_rtx
)
{
switch
((
int
)
size
)
{
case
2
:
emit_insn
(
gen_inswl_be
(
insh
,
gen_lowpart
(
HImode
,
src
),
addr
));
break
;
case
4
:
emit_insn
(
gen_insll_be
(
insh
,
gen_lowpart
(
SImode
,
src
),
addr
));
break
;
case
8
:
emit_insn
(
gen_insql_be
(
insh
,
gen_lowpart
(
DImode
,
src
),
addr
));
break
;
}
emit_insn
(
gen_insxh
(
insl
,
gen_lowpart
(
DImode
,
src
),
GEN_INT
(
size
*
8
),
addr
));
}
switch
((
int
)
size
)
{
case
2
:
emit_insn
(
gen_mskxl_be
(
dsth
,
dsth
,
GEN_INT
(
0xffff
),
addr
));
break
;
case
4
:
emit_insn
(
gen_mskxl_be
(
dsth
,
dsth
,
GEN_INT
(
0xffffffff
),
addr
));
break
;
case
8
:
{
#if HOST_BITS_PER_WIDE_INT == 32
rtx
msk
=
immed_double_const
(
0xffffffff
,
0xffffffff
,
DImode
);
#else
rtx
msk
=
immed_double_const
(
0xffffffffffffffff
,
0
,
DImode
);
#endif
emit_insn
(
gen_mskxl_be
(
dsth
,
dsth
,
msk
,
addr
));
}
break
;
}
emit_insn
(
gen_mskxh
(
dstl
,
dstl
,
GEN_INT
(
size
*
8
),
addr
));
}
else
{
addr
=
copy_addr_to_reg
(
plus_constant
(
dsta
,
ofs
));
if
(
src
!=
const0_rtx
)
...
...
@@ -3291,13 +3475,13 @@ alpha_expand_unaligned_store (dst, src, size, ofs)
switch
((
int
)
size
)
{
case
2
:
emit_insn
(
gen_inswl
(
insl
,
gen_lowpart
(
HImode
,
src
),
addr
));
emit_insn
(
gen_inswl_le
(
insl
,
gen_lowpart
(
HImode
,
src
),
addr
));
break
;
case
4
:
emit_insn
(
gen_insll
(
insl
,
gen_lowpart
(
SImode
,
src
),
addr
));
emit_insn
(
gen_insll_le
(
insl
,
gen_lowpart
(
SImode
,
src
),
addr
));
break
;
case
8
:
emit_insn
(
gen_insql
(
insl
,
src
,
addr
));
emit_insn
(
gen_insql_le
(
insl
,
src
,
addr
));
break
;
}
}
...
...
@@ -3307,10 +3491,10 @@ alpha_expand_unaligned_store (dst, src, size, ofs)
switch
((
int
)
size
)
{
case
2
:
emit_insn
(
gen_mskxl
(
dstl
,
dstl
,
GEN_INT
(
0xffff
),
addr
));
emit_insn
(
gen_mskxl_le
(
dstl
,
dstl
,
GEN_INT
(
0xffff
),
addr
));
break
;
case
4
:
emit_insn
(
gen_mskxl
(
dstl
,
dstl
,
GEN_INT
(
0xffffffff
),
addr
));
emit_insn
(
gen_mskxl_le
(
dstl
,
dstl
,
GEN_INT
(
0xffffffff
),
addr
));
break
;
case
8
:
{
...
...
@@ -3319,10 +3503,11 @@ alpha_expand_unaligned_store (dst, src, size, ofs)
#else
rtx
msk
=
immed_double_const
(
0xffffffffffffffff
,
0
,
DImode
);
#endif
emit_insn
(
gen_mskxl
(
dstl
,
dstl
,
msk
,
addr
));
emit_insn
(
gen_mskxl_le
(
dstl
,
dstl
,
msk
,
addr
));
}
break
;
}
}
if
(
src
!=
const0_rtx
)
{
...
...
@@ -3330,9 +3515,17 @@ alpha_expand_unaligned_store (dst, src, size, ofs)
dstl
=
expand_binop
(
DImode
,
ior_optab
,
insl
,
dstl
,
dstl
,
0
,
OPTAB_WIDEN
);
}
if
(
WORDS_BIG_ENDIAN
)
{
emit_move_insn
(
meml
,
dstl
);
emit_move_insn
(
memh
,
dsth
);
}
else
{
/* Must store high before low for degenerate case of aligned. */
emit_move_insn
(
memh
,
dsth
);
emit_move_insn
(
meml
,
dstl
);
}
}
/* The block move code tries to maximize speed by separating loads and
...
...
@@ -3397,11 +3590,20 @@ alpha_expand_unaligned_load_words (out_regs, smem, words, ofs)
sreg
=
copy_addr_to_reg
(
smema
);
areg
=
expand_binop
(
DImode
,
and_optab
,
sreg
,
GEN_INT
(
7
),
NULL
,
1
,
OPTAB_WIDEN
);
if
(
WORDS_BIG_ENDIAN
)
emit_move_insn
(
sreg
,
plus_constant
(
sreg
,
7
));
for
(
i
=
0
;
i
<
words
;
++
i
)
{
emit_insn
(
gen_extxl
(
data_regs
[
i
],
data_regs
[
i
],
i64
,
sreg
));
emit_insn
(
gen_extqh
(
ext_tmps
[
i
],
data_regs
[
i
+
1
],
sreg
));
if
(
WORDS_BIG_ENDIAN
)
{
emit_insn
(
gen_extqh_be
(
data_regs
[
i
],
data_regs
[
i
],
sreg
));
emit_insn
(
gen_extxl_be
(
ext_tmps
[
i
],
data_regs
[
i
+
1
],
i64
,
sreg
));
}
else
{
emit_insn
(
gen_extxl_le
(
data_regs
[
i
],
data_regs
[
i
],
i64
,
sreg
));
emit_insn
(
gen_extqh_le
(
ext_tmps
[
i
],
data_regs
[
i
+
1
],
sreg
));
}
emit_insn
(
gen_rtx_SET
(
VOIDmode
,
ext_tmps
[
i
],
gen_rtx_IF_THEN_ELSE
(
DImode
,
gen_rtx_EQ
(
DImode
,
areg
,
...
...
@@ -3468,12 +3670,22 @@ alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
/* Shift the input data into place. */
dreg
=
copy_addr_to_reg
(
dmema
);
if
(
WORDS_BIG_ENDIAN
)
emit_move_insn
(
dreg
,
plus_constant
(
dreg
,
7
));
if
(
data_regs
!=
NULL
)
{
for
(
i
=
words
-
1
;
i
>=
0
;
--
i
)
{
if
(
WORDS_BIG_ENDIAN
)
{
emit_insn
(
gen_insql_be
(
ins_tmps
[
i
],
data_regs
[
i
],
dreg
));
emit_insn
(
gen_insxh
(
data_regs
[
i
],
data_regs
[
i
],
i64
,
dreg
));
}
else
{
emit_insn
(
gen_insxh
(
ins_tmps
[
i
],
data_regs
[
i
],
i64
,
dreg
));
emit_insn
(
gen_insql
(
data_regs
[
i
],
data_regs
[
i
],
dreg
));
emit_insn
(
gen_insql_le
(
data_regs
[
i
],
data_regs
[
i
],
dreg
));
}
}
for
(
i
=
words
-
1
;
i
>
0
;
--
i
)
{
...
...
@@ -3484,8 +3696,16 @@ alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
}
/* Split and merge the ends with the destination data. */
if
(
WORDS_BIG_ENDIAN
)
{
emit_insn
(
gen_mskxl_be
(
st_tmp_2
,
st_tmp_2
,
im1
,
dreg
));
emit_insn
(
gen_mskxh
(
st_tmp_1
,
st_tmp_1
,
i64
,
dreg
));
}
else
{
emit_insn
(
gen_mskxh
(
st_tmp_2
,
st_tmp_2
,
i64
,
dreg
));
emit_insn
(
gen_mskxl
(
st_tmp_1
,
st_tmp_1
,
im1
,
dreg
));
emit_insn
(
gen_mskxl_le
(
st_tmp_1
,
st_tmp_1
,
im1
,
dreg
));
}
if
(
data_regs
!=
NULL
)
{
...
...
@@ -3496,16 +3716,23 @@ alpha_expand_unaligned_store_words (data_regs, dmem, words, ofs)
}
/* Store it all. */
if
(
WORDS_BIG_ENDIAN
)
emit_move_insn
(
st_addr_1
,
st_tmp_1
);
else
emit_move_insn
(
st_addr_2
,
st_tmp_2
);
for
(
i
=
words
-
1
;
i
>
0
;
--
i
)
{
rtx
tmp
=
change_address
(
dmem
,
DImode
,
gen_rtx_AND
(
DImode
,
plus_constant
(
dmema
,
i
*
8
),
plus_constant
(
dmema
,
WORDS_BIG_ENDIAN
?
i
*
8
-
1
:
i
*
8
),
im8
));
set_mem_alias_set
(
tmp
,
0
);
emit_move_insn
(
tmp
,
data_regs
?
ins_tmps
[
i
-
1
]
:
const0_rtx
);
}
if
(
WORDS_BIG_ENDIAN
)
emit_move_insn
(
st_addr_2
,
st_tmp_2
);
else
emit_move_insn
(
st_addr_1
,
st_tmp_1
);
}
...
...
@@ -4312,6 +4539,45 @@ alpha_variable_issue (dump, verbose, insn, cim)
}
/* Register global variables and machine-specific functions with the
garbage collector. */
#if TARGET_ABI_UNICOSMK
static
void
alpha_init_machine_status
(
p
)
struct
function
*
p
;
{
p
->
machine
=
(
struct
machine_function
*
)
xcalloc
(
1
,
sizeof
(
struct
machine_function
));
p
->
machine
->
first_ciw
=
NULL_RTX
;
p
->
machine
->
last_ciw
=
NULL_RTX
;
p
->
machine
->
ciw_count
=
0
;
p
->
machine
->
addr_list
=
NULL_RTX
;
}
static
void
alpha_mark_machine_status
(
p
)
struct
function
*
p
;
{
struct
machine_function
*
machine
=
p
->
machine
;
if
(
machine
)
{
ggc_mark_rtx
(
machine
->
first_ciw
);
ggc_mark_rtx
(
machine
->
addr_list
);
}
}
static
void
alpha_free_machine_status
(
p
)
struct
function
*
p
;
{
free
(
p
->
machine
);
p
->
machine
=
NULL
;
}
#endif
/* TARGET_ABI_UNICOSMK */
/* Functions to save and restore alpha_return_addr_rtx. */
/* Start the ball rolling with RETURN_ADDR_RTX. */
...
...
@@ -4478,8 +4744,8 @@ print_operand (file, x, code)
const
char
*
round
=
get_round_mode_suffix
();
if
(
trap
||
round
)
fprintf
(
file
,
"%s%s"
,
(
trap
?
trap
:
""
),
(
round
?
round
:
""
));
fprintf
(
file
,
(
TARGET_AS_SLASH_BEFORE_SUFFIX
?
"/%s%s"
:
"%s%s"
),
(
trap
?
trap
:
""
),
(
round
?
round
:
""
));
break
;
}
...
...
@@ -4648,13 +4914,20 @@ print_operand (file, x, code)
break
;
case
's'
:
/* Write the constant value divided by 8. */
/* Write the constant value divided by 8 for little-endian mode or
(56 - value) / 8 for big-endian mode. */
if
(
GET_CODE
(
x
)
!=
CONST_INT
&&
(
unsigned
HOST_WIDE_INT
)
INTVAL
(
x
)
>=
64
&&
(
INTVAL
(
x
)
&
7
)
!=
8
)
||
(
unsigned
HOST_WIDE_INT
)
INTVAL
(
x
)
>=
(
WORDS_BIG_ENDIAN
?
56
:
64
)
||
(
INTVAL
(
x
)
&
7
)
!=
0
)
output_operand_lossage
(
"invalid %%s value"
);
fprintf
(
file
,
HOST_WIDE_INT_PRINT_DEC
,
INTVAL
(
x
)
/
8
);
fprintf
(
file
,
HOST_WIDE_INT_PRINT_DEC
,
WORDS_BIG_ENDIAN
?
(
56
-
INTVAL
(
x
))
/
8
:
INTVAL
(
x
)
/
8
);
break
;
case
'S'
:
...
...
@@ -4668,6 +4941,18 @@ print_operand (file, x, code)
fprintf
(
file
,
HOST_WIDE_INT_PRINT_DEC
,
(
64
-
INTVAL
(
x
))
/
8
);
break
;
case
't'
:
{
/* On Unicos/Mk systems: use a DEX expression if the symbol
clashes with a register name. */
int
dex
=
unicosmk_need_dex
(
x
);
if
(
dex
)
fprintf
(
file
,
"DEX(%d)"
,
dex
);
else
output_addr_const
(
file
,
x
);
}
break
;
case
'C'
:
case
'D'
:
case
'c'
:
case
'd'
:
/* Write out comparison name. */
{
...
...
@@ -4878,14 +5163,92 @@ function_arg (cum, mode, type, named)
int
basereg
;
int
num_args
;
/* Set up defaults for FP operands passed in FP registers, and
integral operands passed in integer registers. */
if
(
TARGET_FPREGS
&&
(
GET_MODE_CLASS
(
mode
)
==
MODE_COMPLEX_FLOAT
||
GET_MODE_CLASS
(
mode
)
==
MODE_FLOAT
))
basereg
=
32
+
16
;
else
basereg
=
16
;
/* ??? Irritatingly, the definition of CUMULATIVE_ARGS is different for
the three platforms, so we can't avoid conditional compilation. */
#if TARGET_ABI_OPEN_VMS
{
if
(
mode
==
VOIDmode
)
return
alpha_arg_info_reg_val
(
cum
);
num_args
=
cum
.
num_args
;
if
(
num_args
>=
6
||
MUST_PASS_IN_STACK
(
mode
,
type
))
return
NULL_RTX
;
}
#else
#if TARGET_ABI_UNICOSMK
{
int
size
;
/* If this is the last argument, generate the call info word (CIW). */
/* ??? We don't include the caller's line number in the CIW because
I don't know how to determine it if debug infos are turned off. */
if
(
mode
==
VOIDmode
)
{
int
i
;
HOST_WIDE_INT
lo
;
HOST_WIDE_INT
hi
;
rtx
ciw
;
lo
=
0
;
for
(
i
=
0
;
i
<
cum
.
num_reg_words
&&
i
<
5
;
i
++
)
if
(
cum
.
reg_args_type
[
i
])
lo
|=
(
1
<<
(
7
-
i
));
if
(
cum
.
num_reg_words
==
6
&&
cum
.
reg_args_type
[
5
])
lo
|=
7
;
else
lo
|=
cum
.
num_reg_words
;
#if HOST_BITS_PER_WIDE_INT == 32
hi
=
(
cum
.
num_args
<<
20
)
|
cum
.
num_arg_words
;
#else
lo
=
lo
|
(
cum
.
num_args
<<
52
)
|
(
cum
.
num_arg_words
<<
32
);
hi
=
0
;
#endif
ciw
=
immed_double_const
(
lo
,
hi
,
DImode
);
return
gen_rtx_UNSPEC
(
DImode
,
gen_rtvec
(
1
,
ciw
),
UNSPEC_UMK_LOAD_CIW
);
}
size
=
ALPHA_ARG_SIZE
(
mode
,
type
,
named
);
num_args
=
cum
.
num_reg_words
;
if
(
MUST_PASS_IN_STACK
(
mode
,
type
)
||
cum
.
num_reg_words
+
size
>
6
||
cum
.
force_stack
)
return
NULL_RTX
;
else
if
(
type
&&
TYPE_MODE
(
type
)
==
BLKmode
)
{
rtx
reg1
,
reg2
;
reg1
=
gen_rtx_REG
(
DImode
,
num_args
+
16
);
reg1
=
gen_rtx_EXPR_LIST
(
DImode
,
reg1
,
const0_rtx
);
/* The argument fits in two registers. Note that we still need to
reserve a register for empty structures. */
if
(
size
==
0
)
return
NULL_RTX
;
else
if
(
size
==
1
)
return
gen_rtx_PARALLEL
(
mode
,
gen_rtvec
(
1
,
reg1
));
else
{
reg2
=
gen_rtx_REG
(
DImode
,
num_args
+
17
);
reg2
=
gen_rtx_EXPR_LIST
(
DImode
,
reg2
,
GEN_INT
(
8
));
return
gen_rtx_PARALLEL
(
mode
,
gen_rtvec
(
2
,
reg1
,
reg2
));
}
}
}
#else
{
if
(
cum
>=
6
)
return
NULL_RTX
;
num_args
=
cum
;
...
...
@@ -4897,13 +5260,9 @@ function_arg (cum, mode, type, named)
return
NULL_RTX
;
else
if
(
FUNCTION_ARG_PASS_BY_REFERENCE
(
cum
,
mode
,
type
,
named
))
basereg
=
16
;
}
#endif
/* TARGET_ABI_UNICOSMK */
#endif
/* TARGET_ABI_OPEN_VMS */
else
if
(
TARGET_FPREGS
&&
(
GET_MODE_CLASS
(
mode
)
==
MODE_COMPLEX_FLOAT
||
GET_MODE_CLASS
(
mode
)
==
MODE_FLOAT
))
basereg
=
32
+
16
;
else
basereg
=
16
;
return
gen_rtx_REG
(
mode
,
num_args
+
basereg
);
}
...
...
@@ -4913,7 +5272,7 @@ alpha_build_va_list ()
{
tree
base
,
ofs
,
record
,
type_decl
;
if
(
TARGET_ABI_OPEN_VMS
)
if
(
TARGET_ABI_OPEN_VMS
||
TARGET_ABI_UNICOSMK
)
return
ptr_type_node
;
record
=
make_lang_type
(
RECORD_TYPE
);
...
...
@@ -4950,7 +5309,7 @@ alpha_va_start (stdarg_p, valist, nextarg)
if
(
TREE_CODE
(
TREE_TYPE
(
valist
))
==
ERROR_MARK
)
return
;
if
(
TARGET_ABI_OPEN_VMS
)
if
(
TARGET_ABI_OPEN_VMS
||
TARGET_ABI_UNICOSMK
)
std_expand_builtin_va_start
(
stdarg_p
,
valist
,
nextarg
);
/* For Unix, SETUP_INCOMING_VARARGS moves the starting address base
...
...
@@ -4998,7 +5357,7 @@ alpha_va_arg (valist, type)
tree
wide_type
,
wide_ofs
;
int
indirect
=
0
;
if
(
TARGET_ABI_OPEN_VMS
)
if
(
TARGET_ABI_OPEN_VMS
||
TARGET_ABI_UNICOSMK
)
return
std_expand_builtin_va_arg
(
valist
,
type
);
tsize
=
((
TREE_INT_CST_LOW
(
TYPE_SIZE
(
type
))
/
BITS_PER_UNIT
+
7
)
/
8
)
*
8
;
...
...
@@ -5067,7 +5426,7 @@ alpha_va_arg (valist, type)
descriptior to generate. */
/* Nonzero if we need a stack procedure. */
static
int
vms
_is_stack_procedure
;
static
int
alpha
_is_stack_procedure
;
/* Register number (either FP or SP) that is used to unwind the frame. */
static
int
vms_unwind_regno
;
...
...
@@ -5095,13 +5454,14 @@ alpha_sa_mask (imaskP, fmaskP)
if
(
!
current_function_is_thunk
)
#endif
{
if
(
TARGET_ABI_OPEN_VMS
&&
vms
_is_stack_procedure
)
if
(
TARGET_ABI_OPEN_VMS
&&
alpha
_is_stack_procedure
)
imask
|=
(
1L
<<
HARD_FRAME_POINTER_REGNUM
);
/* One for every register we have to save. */
for
(
i
=
0
;
i
<
FIRST_PSEUDO_REGISTER
;
i
++
)
if
(
!
fixed_regs
[
i
]
&&
!
call_used_regs
[
i
]
&&
regs_ever_live
[
i
]
&&
i
!=
REG_RA
)
&&
regs_ever_live
[
i
]
&&
i
!=
REG_RA
&&
(
!
TARGET_ABI_UNICOSMK
||
i
!=
HARD_FRAME_POINTER_REGNUM
))
{
if
(
i
<
32
)
imask
|=
(
1L
<<
i
);
...
...
@@ -5121,9 +5481,15 @@ alpha_sa_mask (imaskP, fmaskP)
}
}
if
(
!
TARGET_ABI_UNICOSMK
)
{
/* If any register spilled, then spill the return address also. */
/* ??? This is required by the Digital stack unwind specification
and isn't needed if we're doing Dwarf2 unwinding. */
if
(
imask
||
fmask
||
alpha_ra_ever_killed
())
imask
|=
(
1L
<<
REG_RA
);
}
}
*
imaskP
=
imask
;
*
fmaskP
=
fmask
;
...
...
@@ -5141,19 +5507,55 @@ alpha_sa_size ()
else
#endif
{
if
(
TARGET_ABI_UNICOSMK
)
{
for
(
i
=
9
;
i
<
15
&&
sa_size
==
0
;
i
++
)
if
(
!
fixed_regs
[
i
]
&&
!
call_used_regs
[
i
]
&&
regs_ever_live
[
i
])
sa_size
=
14
;
for
(
i
=
32
+
2
;
i
<
32
+
10
&&
sa_size
==
0
;
i
++
)
if
(
!
fixed_regs
[
i
]
&&
!
call_used_regs
[
i
]
&&
regs_ever_live
[
i
])
sa_size
=
14
;
}
else
{
/* One for every register we have to save. */
for
(
i
=
0
;
i
<
FIRST_PSEUDO_REGISTER
;
i
++
)
if
(
!
fixed_regs
[
i
]
&&
!
call_used_regs
[
i
]
&&
regs_ever_live
[
i
]
&&
i
!=
REG_RA
)
sa_size
++
;
}
}
if
(
TARGET_ABI_OPEN_VMS
)
if
(
TARGET_ABI_UNICOSMK
)
{
/* We might not need to generate a frame if we don't make any calls
(including calls to __T3E_MISMATCH if this is a vararg function),
don't have any local variables which require stack slots, don't
use alloca and have not determined that we need a frame for other
reasons. */
alpha_is_stack_procedure
=
sa_size
!=
0
||
alpha_ra_ever_killed
()
||
get_frame_size
()
!=
0
||
current_function_outgoing_args_size
||
current_function_varargs
||
current_function_stdarg
||
current_function_calls_alloca
||
frame_pointer_needed
;
/* Always reserve space for saving callee-saved registers if we
need a frame as required by the calling convention. */
if
(
alpha_is_stack_procedure
)
sa_size
=
14
;
}
else
if
(
TARGET_ABI_OPEN_VMS
)
{
/* Start by assuming we can use a register procedure if we don't
make any calls (REG_RA not used) or need to save any
registers and a stack procedure if we do. */
vms
_is_stack_procedure
=
sa_size
!=
0
||
alpha_ra_ever_killed
();
alpha
_is_stack_procedure
=
sa_size
!=
0
||
alpha_ra_ever_killed
();
/* Decide whether to refer to objects off our PV via FP or PV.
If we need FP for something else or if we receive a nonlocal
...
...
@@ -5161,7 +5563,7 @@ alpha_sa_size ()
Otherwise, start by assuming we can use FP. */
vms_base_regno
=
(
frame_pointer_needed
||
current_function_has_nonlocal_label
||
vms
_is_stack_procedure
||
alpha
_is_stack_procedure
||
current_function_outgoing_args_size
?
REG_PV
:
HARD_FRAME_POINTER_REGNUM
);
...
...
@@ -5175,21 +5577,21 @@ alpha_sa_size ()
vms_save_fp_regno
=
i
;
if
(
vms_save_fp_regno
==
-
1
)
vms_base_regno
=
REG_PV
,
vms
_is_stack_procedure
=
1
;
vms_base_regno
=
REG_PV
,
alpha
_is_stack_procedure
=
1
;
/* Stack unwinding should be done via FP unless we use it for PV. */
vms_unwind_regno
=
(
vms_base_regno
==
REG_PV
?
HARD_FRAME_POINTER_REGNUM
:
STACK_POINTER_REGNUM
);
/* If this is a stack procedure, allow space for saving FP and RA. */
if
(
vms
_is_stack_procedure
)
if
(
alpha
_is_stack_procedure
)
sa_size
+=
2
;
}
else
{
/* If some registers were saved but not RA, RA must also be saved,
so leave space for it. */
if
(
sa_size
!=
0
||
alpha_ra_ever_killed
(
))
if
(
!
TARGET_ABI_UNICOSMK
&&
(
sa_size
!=
0
||
alpha_ra_ever_killed
()
))
sa_size
++
;
/* Our size must be even (multiple of 16 bytes). */
...
...
@@ -5204,7 +5606,7 @@ int
alpha_pv_save_size
()
{
alpha_sa_size
();
return
vms
_is_stack_procedure
?
8
:
0
;
return
alpha
_is_stack_procedure
?
8
:
0
;
}
int
...
...
@@ -5243,8 +5645,8 @@ alpha_does_function_need_gp ()
{
rtx
insn
;
/*
We never need a GP for Windows/NT or VMS
. */
if
(
TARGET_ABI_WINDOWS_NT
||
TARGET_ABI_OPEN_VMS
)
/*
The GP being variable is an OSF abi thing
. */
if
(
!
TARGET_ABI_OSF
)
return
0
;
if
(
TARGET_PROFILING_NEEDS_GP
&&
profile_flag
)
...
...
@@ -5358,9 +5760,15 @@ alpha_expand_prologue ()
frame_size
=
get_frame_size
();
if
(
TARGET_ABI_OPEN_VMS
)
frame_size
=
ALPHA_ROUND
(
sa_size
+
(
vms
_is_stack_procedure
?
8
:
0
)
+
(
alpha
_is_stack_procedure
?
8
:
0
)
+
frame_size
+
current_function_pretend_args_size
);
else
if
(
TARGET_ABI_UNICOSMK
)
/* We have to allocate space for the DSIB if we generate a frame. */
frame_size
=
ALPHA_ROUND
(
sa_size
+
(
alpha_is_stack_procedure
?
48
:
0
))
+
ALPHA_ROUND
(
frame_size
+
current_function_outgoing_args_size
);
else
frame_size
=
(
ALPHA_ROUND
(
current_function_outgoing_args_size
)
+
sa_size
...
...
@@ -5389,6 +5797,9 @@ alpha_expand_prologue ()
if
(
TARGET_PROFILING_NEEDS_GP
&&
profile_flag
)
emit_insn
(
gen_prologue_mcount
());
if
(
TARGET_ABI_UNICOSMK
)
unicosmk_gen_dsib
(
&
imask
);
/* Adjust the stack by the frame size. If the frame size is > 4096
bytes, we need to be sure we probe somewhere in the first and last
4096 bytes (we can probably get away without the latter test) and
...
...
@@ -5405,7 +5816,9 @@ alpha_expand_prologue ()
int
probed
=
4096
;
do
emit_insn
(
gen_probe_stack
(
GEN_INT
(
-
probed
)));
emit_insn
(
gen_probe_stack
(
GEN_INT
(
TARGET_ABI_UNICOSMK
?
-
probed
+
64
:
-
probed
)));
while
((
probed
+=
8192
)
<
frame_size
);
/* We only have to do this probe if we aren't saving registers. */
...
...
@@ -5415,7 +5828,9 @@ alpha_expand_prologue ()
if
(
frame_size
!=
0
)
FRP
(
emit_insn
(
gen_adddi3
(
stack_pointer_rtx
,
stack_pointer_rtx
,
GEN_INT
(
-
frame_size
))));
GEN_INT
(
TARGET_ABI_UNICOSMK
?
-
frame_size
+
64
:
-
frame_size
))));
}
else
{
...
...
@@ -5432,7 +5847,8 @@ alpha_expand_prologue ()
rtx
seq
;
emit_move_insn
(
count
,
GEN_INT
(
blocks
));
emit_insn
(
gen_adddi3
(
ptr
,
stack_pointer_rtx
,
GEN_INT
(
4096
)));
emit_insn
(
gen_adddi3
(
ptr
,
stack_pointer_rtx
,
GEN_INT
(
TARGET_ABI_UNICOSMK
?
4096
-
64
:
4096
)));
/* Because of the difficulty in emitting a new basic block this
late in the compilation, generate the loop as a single insn. */
...
...
@@ -5479,10 +5895,14 @@ alpha_expand_prologue ()
=
gen_rtx_EXPR_LIST
(
REG_FRAME_RELATED_EXPR
,
gen_rtx_SET
(
VOIDmode
,
stack_pointer_rtx
,
gen_rtx_PLUS
(
Pmode
,
stack_pointer_rtx
,
GEN_INT
(
-
frame_size
))),
GEN_INT
(
TARGET_ABI_UNICOSMK
?
-
frame_size
+
64
:
-
frame_size
))),
REG_NOTES
(
seq
));
}
if
(
!
TARGET_ABI_UNICOSMK
)
{
/* Cope with very large offsets to the register save area. */
sa_reg
=
stack_pointer_rtx
;
if
(
reg_offset
+
sa_size
>
0x8000
)
...
...
@@ -5496,11 +5916,12 @@ alpha_expand_prologue ()
bias
=
reg_offset
,
reg_offset
=
0
;
sa_reg
=
gen_rtx_REG
(
DImode
,
24
);
FRP
(
emit_insn
(
gen_adddi3
(
sa_reg
,
stack_pointer_rtx
,
GEN_INT
(
bias
))));
FRP
(
emit_insn
(
gen_adddi3
(
sa_reg
,
stack_pointer_rtx
,
GEN_INT
(
bias
))));
}
/* Save regs in stack order. Beginning with VMS PV. */
if
(
TARGET_ABI_OPEN_VMS
&&
vms
_is_stack_procedure
)
if
(
TARGET_ABI_OPEN_VMS
&&
alpha
_is_stack_procedure
)
{
mem
=
gen_rtx_MEM
(
DImode
,
stack_pointer_rtx
);
set_mem_alias_set
(
mem
,
alpha_sr_alias_set
);
...
...
@@ -5535,10 +5956,37 @@ alpha_expand_prologue ()
FRP
(
emit_move_insn
(
mem
,
gen_rtx_REG
(
DFmode
,
i
+
32
)));
reg_offset
+=
8
;
}
}
else
if
(
TARGET_ABI_UNICOSMK
&&
alpha_is_stack_procedure
)
{
/* The standard frame on the T3E includes space for saving registers.
We just have to use it. We don't have to save the return address and
the old frame pointer here - they are saved in the DSIB. */
reg_offset
=
-
56
;
for
(
i
=
9
;
i
<
15
;
i
++
)
if
(
imask
&
(
1L
<<
i
))
{
mem
=
gen_rtx_MEM
(
DImode
,
plus_constant
(
hard_frame_pointer_rtx
,
reg_offset
));
set_mem_alias_set
(
mem
,
alpha_sr_alias_set
);
FRP
(
emit_move_insn
(
mem
,
gen_rtx_REG
(
DImode
,
i
)));
reg_offset
-=
8
;
}
for
(
i
=
2
;
i
<
10
;
i
++
)
if
(
fmask
&
(
1L
<<
i
))
{
mem
=
gen_rtx_MEM
(
DFmode
,
plus_constant
(
hard_frame_pointer_rtx
,
reg_offset
));
set_mem_alias_set
(
mem
,
alpha_sr_alias_set
);
FRP
(
emit_move_insn
(
mem
,
gen_rtx_REG
(
DFmode
,
i
+
32
)));
reg_offset
-=
8
;
}
}
if
(
TARGET_ABI_OPEN_VMS
)
{
if
(
!
vms
_is_stack_procedure
)
if
(
!
alpha
_is_stack_procedure
)
/* Register frame procedures save the fp. */
/* ??? Ought to have a dwarf2 save for this. */
emit_move_insn
(
gen_rtx_REG
(
DImode
,
vms_save_fp_regno
),
...
...
@@ -5559,7 +6007,7 @@ alpha_expand_prologue ()
-
(
ALPHA_ROUND
(
current_function_outgoing_args_size
)))));
}
else
else
if
(
!
TARGET_ABI_UNICOSMK
)
{
/* If we need a frame pointer, set it from the stack pointer. */
if
(
frame_pointer_needed
)
...
...
@@ -5607,15 +6055,28 @@ alpha_start_function (file, fnname, decl)
char
*
entry_label
=
(
char
*
)
alloca
(
strlen
(
fnname
)
+
6
);
int
i
;
/* Don't emit an extern directive for functions defined in the same file. */
if
(
TARGET_ABI_UNICOSMK
)
{
tree
name_tree
;
name_tree
=
get_identifier
(
fnname
);
TREE_ASM_WRITTEN
(
name_tree
)
=
1
;
}
alpha_fnname
=
fnname
;
sa_size
=
alpha_sa_size
();
frame_size
=
get_frame_size
();
if
(
TARGET_ABI_OPEN_VMS
)
frame_size
=
ALPHA_ROUND
(
sa_size
+
(
vms
_is_stack_procedure
?
8
:
0
)
+
(
alpha
_is_stack_procedure
?
8
:
0
)
+
frame_size
+
current_function_pretend_args_size
);
else
if
(
TARGET_ABI_UNICOSMK
)
frame_size
=
ALPHA_ROUND
(
sa_size
+
(
alpha_is_stack_procedure
?
48
:
0
))
+
ALPHA_ROUND
(
frame_size
+
current_function_outgoing_args_size
);
else
frame_size
=
(
ALPHA_ROUND
(
current_function_outgoing_args_size
)
+
sa_size
...
...
@@ -5639,15 +6100,20 @@ alpha_start_function (file, fnname, decl)
if
(
write_symbols
==
SDB_DEBUG
)
{
#ifdef ASM_OUTPUT_SOURCE_FILENAME
ASM_OUTPUT_SOURCE_FILENAME
(
file
,
DECL_SOURCE_FILE
(
current_function_decl
));
#endif
#ifdef ASM_OUTPUT_SOURCE_LINE
if
(
debug_info_level
!=
DINFO_LEVEL_TERSE
)
ASM_OUTPUT_SOURCE_LINE
(
file
,
DECL_SOURCE_LINE
(
current_function_decl
));
#endif
}
/* Issue function start and label. */
if
(
TARGET_ABI_OPEN_VMS
||
!
flag_inhibit_size_directive
)
if
(
TARGET_ABI_OPEN_VMS
||
(
!
TARGET_ABI_UNICOSMK
&&
!
flag_inhibit_size_directive
))
{
fputs
(
"
\t
.ent "
,
file
);
assemble_name
(
file
,
fnname
);
...
...
@@ -5666,13 +6132,19 @@ alpha_start_function (file, fnname, decl)
strcpy
(
entry_label
,
fnname
);
if
(
TARGET_ABI_OPEN_VMS
)
strcat
(
entry_label
,
"..en"
);
/* For public functions, the label must be globalized by appending an
additional colon. */
if
(
TARGET_ABI_UNICOSMK
&&
TREE_PUBLIC
(
decl
))
strcat
(
entry_label
,
":"
);
ASM_OUTPUT_LABEL
(
file
,
entry_label
);
inside_function
=
TRUE
;
if
(
TARGET_ABI_OPEN_VMS
)
fprintf
(
file
,
"
\t
.base $%d
\n
"
,
vms_base_regno
);
if
(
!
TARGET_ABI_OPEN_VMS
&&
TARGET_IEEE_CONFORMANT
if
(
!
TARGET_ABI_OPEN_VMS
&&
!
TARGET_ABI_UNICOSMK
&&
TARGET_IEEE_CONFORMANT
&&
!
flag_inhibit_size_directive
)
{
/* Set flags in procedure descriptor to request IEEE-conformant
...
...
@@ -5688,7 +6160,9 @@ alpha_start_function (file, fnname, decl)
/* Describe our frame. If the frame size is larger than an integer,
print it as zero to avoid an assembler error. We won't be
properly describing such a frame, but that's the best we can do. */
if
(
TARGET_ABI_OPEN_VMS
)
if
(
TARGET_ABI_UNICOSMK
)
;
else
if
(
TARGET_ABI_OPEN_VMS
)
{
fprintf
(
file
,
"
\t
.frame $%d,"
,
vms_unwind_regno
);
fprintf
(
file
,
HOST_WIDE_INT_PRINT_DEC
,
...
...
@@ -5708,15 +6182,17 @@ alpha_start_function (file, fnname, decl)
}
/* Describe which registers were spilled. */
if
(
TARGET_ABI_OPEN_VMS
)
if
(
TARGET_ABI_UNICOSMK
)
;
else
if
(
TARGET_ABI_OPEN_VMS
)
{
if
(
imask
)
/* ??? Does VMS care if mask contains ra? The old code did
'n
t
/* ??? Does VMS care if mask contains ra? The old code did
n'
t
set it, so I don't here. */
fprintf
(
file
,
"
\t
.mask 0x%lx,0
\n
"
,
imask
&
~
(
1L
<<
REG_RA
));
if
(
fmask
)
fprintf
(
file
,
"
\t
.fmask 0x%lx,0
\n
"
,
fmask
);
if
(
!
vms
_is_stack_procedure
)
if
(
!
alpha
_is_stack_procedure
)
fprintf
(
file
,
"
\t
.fp_save $%d
\n
"
,
vms_save_fp_regno
);
}
else
if
(
!
flag_inhibit_size_directive
)
...
...
@@ -5760,7 +6236,7 @@ alpha_start_function (file, fnname, decl)
ASM_OUTPUT_LABEL
(
file
,
fnname
);
fprintf
(
file
,
"
\t
.pdesc "
);
assemble_name
(
file
,
fnname
);
fprintf
(
file
,
"..en,%s
\n
"
,
vms
_is_stack_procedure
?
"stack"
:
"reg"
);
fprintf
(
file
,
"..en,%s
\n
"
,
alpha
_is_stack_procedure
?
"stack"
:
"reg"
);
alpha_need_linkage
(
fnname
,
1
);
text_section
();
#endif
...
...
@@ -5772,7 +6248,9 @@ static void
alpha_output_function_end_prologue
(
file
)
FILE
*
file
;
{
if
(
TARGET_ABI_OPEN_VMS
)
if
(
TARGET_ABI_UNICOSMK
)
;
else
if
(
TARGET_ABI_OPEN_VMS
)
fputs
(
"
\t
.prologue
\n
"
,
file
);
else
if
(
TARGET_ABI_WINDOWS_NT
)
fputs
(
"
\t
.prologue 0
\n
"
,
file
);
...
...
@@ -5811,9 +6289,14 @@ alpha_expand_epilogue ()
frame_size
=
get_frame_size
();
if
(
TARGET_ABI_OPEN_VMS
)
frame_size
=
ALPHA_ROUND
(
sa_size
+
(
vms
_is_stack_procedure
?
8
:
0
)
+
(
alpha
_is_stack_procedure
?
8
:
0
)
+
frame_size
+
current_function_pretend_args_size
);
else
if
(
TARGET_ABI_UNICOSMK
)
frame_size
=
ALPHA_ROUND
(
sa_size
+
(
alpha_is_stack_procedure
?
48
:
0
))
+
ALPHA_ROUND
(
frame_size
+
current_function_outgoing_args_size
);
else
frame_size
=
(
ALPHA_ROUND
(
current_function_outgoing_args_size
)
+
sa_size
...
...
@@ -5827,7 +6310,7 @@ alpha_expand_epilogue ()
alpha_sa_mask
(
&
imask
,
&
fmask
);
fp_is_frame_pointer
=
((
TARGET_ABI_OPEN_VMS
&&
vms
_is_stack_procedure
)
fp_is_frame_pointer
=
((
TARGET_ABI_OPEN_VMS
&&
alpha
_is_stack_procedure
)
||
(
!
TARGET_ABI_OPEN_VMS
&&
frame_pointer_needed
));
fp_offset
=
0
;
sa_reg
=
stack_pointer_rtx
;
...
...
@@ -5837,7 +6320,7 @@ alpha_expand_epilogue ()
else
eh_ofs
=
NULL_RTX
;
if
(
sa_size
)
if
(
!
TARGET_ABI_UNICOSMK
&&
sa_size
)
{
/* If we have a frame pointer, restore SP from it. */
if
((
TARGET_ABI_OPEN_VMS
...
...
@@ -5895,6 +6378,38 @@ alpha_expand_epilogue ()
reg_offset
+=
8
;
}
}
else
if
(
TARGET_ABI_UNICOSMK
&&
alpha_is_stack_procedure
)
{
/* Restore callee-saved general-purpose registers. */
reg_offset
=
-
56
;
for
(
i
=
9
;
i
<
15
;
i
++
)
if
(
imask
&
(
1L
<<
i
))
{
mem
=
gen_rtx_MEM
(
DImode
,
plus_constant
(
hard_frame_pointer_rtx
,
reg_offset
));
set_mem_alias_set
(
mem
,
alpha_sr_alias_set
);
FRP
(
emit_move_insn
(
gen_rtx_REG
(
DImode
,
i
),
mem
));
reg_offset
-=
8
;
}
for
(
i
=
2
;
i
<
10
;
i
++
)
if
(
fmask
&
(
1L
<<
i
))
{
mem
=
gen_rtx_MEM
(
DFmode
,
plus_constant
(
hard_frame_pointer_rtx
,
reg_offset
));
set_mem_alias_set
(
mem
,
alpha_sr_alias_set
);
FRP
(
emit_move_insn
(
gen_rtx_REG
(
DFmode
,
i
+
32
),
mem
));
reg_offset
-=
8
;
}
/* Restore the return address from the DSIB. */
mem
=
gen_rtx_MEM
(
DImode
,
plus_constant
(
hard_frame_pointer_rtx
,
-
8
));
set_mem_alias_set
(
mem
,
alpha_sr_alias_set
);
FRP
(
emit_move_insn
(
gen_rtx_REG
(
DImode
,
REG_RA
),
mem
));
}
if
(
frame_size
||
eh_ofs
)
{
...
...
@@ -5910,8 +6425,15 @@ alpha_expand_epilogue ()
/* If the stack size is large, begin computation into a temporary
register so as not to interfere with a potential fp restore,
which must be consecutive with an SP restore. */
if
(
frame_size
<
32768
)
if
(
frame_size
<
32768
&&
!
(
TARGET_ABI_UNICOSMK
&&
current_function_calls_alloca
))
sp_adj2
=
GEN_INT
(
frame_size
);
else
if
(
TARGET_ABI_UNICOSMK
)
{
sp_adj1
=
gen_rtx_REG
(
DImode
,
23
);
FRP
(
emit_move_insn
(
sp_adj1
,
hard_frame_pointer_rtx
));
sp_adj2
=
const0_rtx
;
}
else
if
(
frame_size
<
0x40007fffL
)
{
int
low
=
((
frame_size
&
0xffff
)
^
0x8000
)
-
0x8000
;
...
...
@@ -5944,7 +6466,15 @@ alpha_expand_epilogue ()
/* From now on, things must be in order. So emit blockages. */
/* Restore the frame pointer. */
if
(
fp_is_frame_pointer
)
if
(
TARGET_ABI_UNICOSMK
)
{
emit_insn
(
gen_blockage
());
mem
=
gen_rtx_MEM
(
DImode
,
plus_constant
(
hard_frame_pointer_rtx
,
-
16
));
set_mem_alias_set
(
mem
,
alpha_sr_alias_set
);
FRP
(
emit_move_insn
(
hard_frame_pointer_rtx
,
mem
));
}
else
if
(
fp_is_frame_pointer
)
{
emit_insn
(
gen_blockage
());
mem
=
gen_rtx_MEM
(
DImode
,
plus_constant
(
sa_reg
,
fp_offset
));
...
...
@@ -5960,17 +6490,29 @@ alpha_expand_epilogue ()
/* Restore the stack pointer. */
emit_insn
(
gen_blockage
());
if
(
sp_adj2
==
const0_rtx
)
FRP
(
emit_move_insn
(
stack_pointer_rtx
,
sp_adj1
));
else
FRP
(
emit_move_insn
(
stack_pointer_rtx
,
gen_rtx_PLUS
(
DImode
,
sp_adj1
,
sp_adj2
)));
}
else
{
if
(
TARGET_ABI_OPEN_VMS
&&
!
vms
_is_stack_procedure
)
if
(
TARGET_ABI_OPEN_VMS
&&
!
alpha
_is_stack_procedure
)
{
emit_insn
(
gen_blockage
());
FRP
(
emit_move_insn
(
hard_frame_pointer_rtx
,
gen_rtx_REG
(
DImode
,
vms_save_fp_regno
)));
}
else
if
(
TARGET_ABI_UNICOSMK
&&
!
alpha_is_stack_procedure
)
{
/* Decrement the frame pointer if the function does not have a
frame. */
emit_insn
(
gen_blockage
());
FRP
(
emit_insn
(
gen_adddi3
(
hard_frame_pointer_rtx
,
hard_frame_pointer_rtx
,
GEN_INT
(
-
1
))));
}
}
}
...
...
@@ -5983,7 +6525,7 @@ alpha_end_function (file, fnname, decl)
tree
decl
ATTRIBUTE_UNUSED
;
{
/* End the function. */
if
(
!
flag_inhibit_size_directive
)
if
(
!
TARGET_ABI_UNICOSMK
&&
!
flag_inhibit_size_directive
)
{
fputs
(
"
\t
.end "
,
file
);
assemble_name
(
file
,
fnname
);
...
...
@@ -6000,6 +6542,13 @@ alpha_end_function (file, fnname, decl)
if
(
!
DECL_WEAK
(
current_function_decl
)
&&
(
!
flag_pic
||
!
TREE_PUBLIC
(
current_function_decl
)))
SYMBOL_REF_FLAG
(
XEXP
(
DECL_RTL
(
current_function_decl
),
0
))
=
1
;
/* Output jump tables and the static subroutine information block. */
if
(
TARGET_ABI_UNICOSMK
)
{
unicosmk_output_ssib
(
file
,
fnname
);
unicosmk_output_deferred_case_vectors
(
file
);
}
}
/* Debugging support. */
...
...
@@ -7296,3 +7845,801 @@ alpha_need_linkage (name, is_local)
}
#endif
/* TARGET_ABI_OPEN_VMS */
#if TARGET_ABI_UNICOSMK
static
void
unicosmk_output_module_name
PARAMS
((
FILE
*
));
static
void
unicosmk_output_default_externs
PARAMS
((
FILE
*
));
static
void
unicosmk_output_dex
PARAMS
((
FILE
*
));
static
void
unicosmk_output_externs
PARAMS
((
FILE
*
));
static
void
unicosmk_output_addr_vec
PARAMS
((
FILE
*
,
rtx
));
static
const
char
*
unicosmk_ssib_name
PARAMS
((
void
));
/* Define the offset between two registers, one to be eliminated, and the
other its replacement, at the start of a routine. */
int
unicosmk_initial_elimination_offset
(
from
,
to
)
int
from
;
int
to
;
{
int
fixed_size
;
fixed_size
=
alpha_sa_size
();
if
(
fixed_size
!=
0
)
fixed_size
+=
48
;
if
(
from
==
FRAME_POINTER_REGNUM
&&
to
==
HARD_FRAME_POINTER_REGNUM
)
return
-
fixed_size
;
else
if
(
from
==
ARG_POINTER_REGNUM
&&
to
==
HARD_FRAME_POINTER_REGNUM
)
return
0
;
else
if
(
from
==
FRAME_POINTER_REGNUM
&&
to
==
STACK_POINTER_REGNUM
)
return
(
ALPHA_ROUND
(
current_function_outgoing_args_size
)
+
ALPHA_ROUND
(
get_frame_size
()));
else
if
(
from
==
ARG_POINTER_REGNUM
&&
to
==
STACK_POINTER_REGNUM
)
return
(
ALPHA_ROUND
(
fixed_size
)
+
ALPHA_ROUND
(
get_frame_size
()
+
current_function_outgoing_args_size
));
else
abort
();
}
/* Output the module name for .ident and .end directives. We have to strip
directories and add make sure that the module name starts with a letter
or '$'. */
static
void
unicosmk_output_module_name
(
file
)
FILE
*
file
;
{
const
char
*
name
;
/* Strip directories. */
name
=
strrchr
(
main_input_filename
,
'/'
);
if
(
name
)
++
name
;
else
name
=
main_input_filename
;
/* CAM only accepts module names that start with a letter or '$'. We
prefix the module name with a '$' if necessary. */
if
(
!
ISALPHA
(
*
name
))
fprintf
(
file
,
"$%s"
,
name
);
else
fputs
(
name
,
file
);
}
/* Output text that to appear at the beginning of an assembler file. */
void
unicosmk_asm_file_start
(
file
)
FILE
*
file
;
{
int
i
;
fputs
(
"
\t
.ident
\t
"
,
file
);
unicosmk_output_module_name
(
file
);
fputs
(
"
\n\n
"
,
file
);
/* The Unicos/Mk assembler uses different register names. Instead of trying
to support them, we simply use micro definitions. */
/* CAM has different register names: rN for the integer register N and fN
for the floating-point register N. Instead of trying to use these in
alpha.md, we define the symbols $N and $fN to refer to the appropriate
register. */
for
(
i
=
0
;
i
<
32
;
++
i
)
fprintf
(
file
,
"$%d <- r%d
\n
"
,
i
,
i
);
for
(
i
=
0
;
i
<
32
;
++
i
)
fprintf
(
file
,
"$f%d <- f%d
\n
"
,
i
,
i
);
putc
(
'\n'
,
file
);
/* The .align directive fill unused space with zeroes which does not work
in code sections. We define the macro 'gcc@code@align' which uses nops
instead. Note that it assumes that code sections always have the
biggest possible alignment since . refers to the current offset from
the beginning of the section. */
fputs
(
"
\t
.macro gcc@code@align n
\n
"
,
file
);
fputs
(
"gcc@n@bytes = 1 << n
\n
"
,
file
);
fputs
(
"gcc@here = . % gcc@n@bytes
\n
"
,
file
);
fputs
(
"
\t
.if ne, gcc@here, 0
\n
"
,
file
);
fputs
(
"
\t
.repeat (gcc@n@bytes - gcc@here) / 4
\n
"
,
file
);
fputs
(
"
\t
bis r31,r31,r31
\n
"
,
file
);
fputs
(
"
\t
.endr
\n
"
,
file
);
fputs
(
"
\t
.endif
\n
"
,
file
);
fputs
(
"
\t
.endm gcc@code@align
\n\n
"
,
file
);
/* Output extern declarations which should always be visible. */
unicosmk_output_default_externs
(
file
);
/* Open a dummy section. We always need to be inside a section for the
section-switching code to work correctly.
??? This should be a module id or something like that. I still have to
figure out what the rules for those are. */
fputs
(
"
\n\t
.psect
\t
$SG00000,data
\n
"
,
file
);
}
/* Output text to appear at the end of an assembler file. This includes all
pending extern declarations and DEX expressions. */
void
unicosmk_asm_file_end
(
file
)
FILE
*
file
;
{
fputs
(
"
\t
.endp
\n\n
"
,
file
);
/* Output all pending externs. */
unicosmk_output_externs
(
file
);
/* Output dex definitions used for functions whose names conflict with
register names. */
unicosmk_output_dex
(
file
);
fputs
(
"
\t
.end
\t
"
,
file
);
unicosmk_output_module_name
(
file
);
putc
(
'\n'
,
file
);
}
/* Output the definition of a common variable. */
void
unicosmk_output_common
(
file
,
name
,
size
,
align
)
FILE
*
file
;
const
char
*
name
;
int
size
;
int
align
;
{
tree
name_tree
;
printf
(
"T3E__: common %s
\n
"
,
name
);
common_section
();
fputs
(
"
\t
.endp
\n\n\t
.psect "
,
file
);
assemble_name
(
file
,
name
);
fprintf
(
file
,
",%d,common
\n
"
,
floor_log2
(
align
/
BITS_PER_UNIT
));
fprintf
(
file
,
"
\t
.byte
\t
0:%d
\n
"
,
size
);
/* Mark the symbol as defined in this module. */
name_tree
=
get_identifier
(
name
);
TREE_ASM_WRITTEN
(
name_tree
)
=
1
;
}
#define SECTION_PUBLIC SECTION_MACH_DEP
#define SECTION_MAIN (SECTION_PUBLIC << 1)
static
int
current_section_align
;
static
unsigned
int
unicosmk_section_type_flags
(
decl
,
name
,
reloc
)
tree
decl
;
const
char
*
name
;
int
reloc
ATTRIBUTE_UNUSED
;
{
unsigned
int
flags
=
default_section_type_flags
(
decl
,
name
,
reloc
);
if
(
!
decl
)
return
flags
;
if
(
TREE_CODE
(
decl
)
==
FUNCTION_DECL
)
{
current_section_align
=
floor_log2
(
FUNCTION_BOUNDARY
/
BITS_PER_UNIT
);
if
(
align_functions_log
>
current_section_align
)
current_section_align
=
align_functions_log
;
if
(
!
strcmp
(
IDENTIFIER_POINTER
(
DECL_ASSEMBLER_NAME
(
decl
)),
"main"
))
flags
|=
SECTION_MAIN
;
}
else
current_section_align
=
floor_log2
(
DECL_ALIGN
(
decl
)
/
BITS_PER_UNIT
);
if
(
TREE_PUBLIC
(
decl
))
flags
|=
SECTION_PUBLIC
;
return
flags
;
}
/* Generate a section name for decl and associate it with the
declaration. */
void
unicosmk_unique_section
(
decl
,
reloc
)
tree
decl
;
int
reloc
ATTRIBUTE_UNUSED
;
{
const
char
*
name
;
int
len
;
if
(
!
decl
)
abort
();
name
=
IDENTIFIER_POINTER
(
DECL_ASSEMBLER_NAME
(
decl
));
STRIP_NAME_ENCODING
(
name
,
name
);
len
=
strlen
(
name
);
if
(
TREE_CODE
(
decl
)
==
FUNCTION_DECL
)
{
char
*
string
;
/* It is essential that we prefix the section name here because
otherwise the section names generated for constructors and
destructors confuse collect2. */
string
=
alloca
(
len
+
6
);
sprintf
(
string
,
"code@%s"
,
name
);
DECL_SECTION_NAME
(
decl
)
=
build_string
(
len
+
5
,
string
);
}
else
if
(
TREE_PUBLIC
(
decl
))
DECL_SECTION_NAME
(
decl
)
=
build_string
(
len
,
name
);
else
{
char
*
string
;
string
=
alloca
(
len
+
6
);
sprintf
(
string
,
"data@%s"
,
name
);
DECL_SECTION_NAME
(
decl
)
=
build_string
(
len
+
5
,
string
);
}
}
/* Switch to an arbitrary section NAME with attributes as specified
by FLAGS. ALIGN specifies any known alignment requirements for
the section; 0 if the default should be used. */
static
void
unicosmk_asm_named_section
(
name
,
flags
)
const
char
*
name
;
unsigned
int
flags
;
{
const
char
*
kind
;
/* Close the previous section. */
fputs
(
"
\t
.endp
\n\n
"
,
asm_out_file
);
/* Find out what kind of section we are opening. */
if
(
flags
&
SECTION_MAIN
)
fputs
(
"
\t
.start
\t
main
\n
"
,
asm_out_file
);
if
(
flags
&
SECTION_CODE
)
kind
=
"code"
;
else
if
(
flags
&
SECTION_PUBLIC
)
kind
=
"common"
;
else
kind
=
"data"
;
if
(
current_section_align
!=
0
)
fprintf
(
asm_out_file
,
"
\t
.psect
\t
%s,%d,%s
\n
"
,
name
,
current_section_align
,
kind
);
else
fprintf
(
asm_out_file
,
"
\t
.psect
\t
%s,%s
\n
"
,
name
,
kind
);
}
static
void
unicosmk_insert_attributes
(
decl
,
attr_ptr
)
tree
decl
;
tree
*
attr_ptr
ATTRIBUTE_UNUSED
;
{
if
(
DECL_P
(
decl
)
&&
(
TREE_PUBLIC
(
decl
)
||
TREE_CODE
(
decl
)
==
FUNCTION_DECL
))
UNIQUE_SECTION
(
decl
,
0
);
}
/* Output an alignment directive. We have to use the macro 'gcc@code@align'
in code sections because .align fill unused space with zeroes. */
void
unicosmk_output_align
(
file
,
align
)
FILE
*
file
;
int
align
;
{
if
(
inside_function
)
fprintf
(
file
,
"
\t
gcc@code@align
\t
%d
\n
"
,
align
);
else
fprintf
(
file
,
"
\t
.align
\t
%d
\n
"
,
align
);
}
/* Add a case vector to the current function's list of deferred case
vectors. Case vectors have to be put into a separate section because CAM
does not allow data definitions in code sections. */
void
unicosmk_defer_case_vector
(
lab
,
vec
)
rtx
lab
;
rtx
vec
;
{
struct
machine_function
*
machine
=
cfun
->
machine
;
vec
=
gen_rtx_EXPR_LIST
(
VOIDmode
,
lab
,
vec
);
machine
->
addr_list
=
gen_rtx_EXPR_LIST
(
VOIDmode
,
vec
,
machine
->
addr_list
);
}
/* Output a case vector. */
static
void
unicosmk_output_addr_vec
(
file
,
vec
)
FILE
*
file
;
rtx
vec
;
{
rtx
lab
=
XEXP
(
vec
,
0
);
rtx
body
=
XEXP
(
vec
,
1
);
int
vlen
=
XVECLEN
(
body
,
0
);
int
idx
;
ASM_OUTPUT_INTERNAL_LABEL
(
file
,
"L"
,
CODE_LABEL_NUMBER
(
lab
));
for
(
idx
=
0
;
idx
<
vlen
;
idx
++
)
{
ASM_OUTPUT_ADDR_VEC_ELT
(
file
,
CODE_LABEL_NUMBER
(
XEXP
(
XVECEXP
(
body
,
0
,
idx
),
0
)));
}
}
/* Output current function's deferred case vectors. */
static
void
unicosmk_output_deferred_case_vectors
(
file
)
FILE
*
file
;
{
struct
machine_function
*
machine
=
cfun
->
machine
;
rtx
t
;
if
(
machine
->
addr_list
==
NULL_RTX
)
return
;
data_section
();
for
(
t
=
machine
->
addr_list
;
t
;
t
=
XEXP
(
t
,
1
))
unicosmk_output_addr_vec
(
file
,
XEXP
(
t
,
0
));
}
/* Set up the dynamic subprogram information block (DSIB) and update the
frame pointer register ($15) for subroutines which have a frame. If the
subroutine doesn't have a frame, simply increment $15. */
static
void
unicosmk_gen_dsib
(
imaskP
)
unsigned
long
*
imaskP
;
{
if
(
alpha_is_stack_procedure
)
{
const
char
*
ssib_name
;
rtx
mem
;
/* Allocate 64 bytes for the DSIB. */
FRP
(
emit_insn
(
gen_adddi3
(
stack_pointer_rtx
,
stack_pointer_rtx
,
GEN_INT
(
-
64
))));
emit_insn
(
gen_blockage
());
/* Save the return address. */
mem
=
gen_rtx_MEM
(
DImode
,
plus_constant
(
stack_pointer_rtx
,
56
));
set_mem_alias_set
(
mem
,
alpha_sr_alias_set
);
FRP
(
emit_move_insn
(
mem
,
gen_rtx_REG
(
DImode
,
REG_RA
)));
(
*
imaskP
)
&=
~
(
1L
<<
REG_RA
);
/* Save the old frame pointer. */
mem
=
gen_rtx_MEM
(
DImode
,
plus_constant
(
stack_pointer_rtx
,
48
));
set_mem_alias_set
(
mem
,
alpha_sr_alias_set
);
FRP
(
emit_move_insn
(
mem
,
hard_frame_pointer_rtx
));
(
*
imaskP
)
&=
~
(
1L
<<
HARD_FRAME_POINTER_REGNUM
);
emit_insn
(
gen_blockage
());
/* Store the SSIB pointer. */
ssib_name
=
ggc_strdup
(
unicosmk_ssib_name
());
mem
=
gen_rtx_MEM
(
DImode
,
plus_constant
(
stack_pointer_rtx
,
32
));
set_mem_alias_set
(
mem
,
alpha_sr_alias_set
);
FRP
(
emit_move_insn
(
gen_rtx_REG
(
DImode
,
5
),
gen_rtx_SYMBOL_REF
(
Pmode
,
ssib_name
)));
FRP
(
emit_move_insn
(
mem
,
gen_rtx_REG
(
DImode
,
5
)));
/* Save the CIW index. */
mem
=
gen_rtx_MEM
(
DImode
,
plus_constant
(
stack_pointer_rtx
,
24
));
set_mem_alias_set
(
mem
,
alpha_sr_alias_set
);
FRP
(
emit_move_insn
(
mem
,
gen_rtx_REG
(
DImode
,
25
)));
emit_insn
(
gen_blockage
());
/* Set the new frame pointer. */
FRP
(
emit_insn
(
gen_adddi3
(
hard_frame_pointer_rtx
,
stack_pointer_rtx
,
GEN_INT
(
64
))));
}
else
{
/* Increment the frame pointer register to indicate that we do not
have a frame. */
FRP
(
emit_insn
(
gen_adddi3
(
hard_frame_pointer_rtx
,
hard_frame_pointer_rtx
,
GEN_INT
(
1
))));
}
}
#define SSIB_PREFIX "__SSIB_"
#define SSIB_PREFIX_LEN 7
/* Generate the name of the SSIB section for the current function. */
static
const
char
*
unicosmk_ssib_name
()
{
/* This is ok since CAM won't be able to deal with names longer than that
anyway. */
static
char
name
[
256
];
rtx
x
;
const
char
*
fnname
;
char
*
ssib_name
;
int
len
;
x
=
DECL_RTL
(
cfun
->
decl
);
if
(
GET_CODE
(
x
)
!=
MEM
)
abort
();
x
=
XEXP
(
x
,
0
);
if
(
GET_CODE
(
x
)
!=
SYMBOL_REF
)
abort
();
fnname
=
XSTR
(
x
,
0
);
STRIP_NAME_ENCODING
(
fnname
,
fnname
);
len
=
strlen
(
fnname
);
if
(
len
+
SSIB_PREFIX_LEN
>
255
)
len
=
255
-
SSIB_PREFIX_LEN
;
strcpy
(
name
,
SSIB_PREFIX
);
strncpy
(
name
+
SSIB_PREFIX_LEN
,
fnname
,
len
);
name
[
len
+
SSIB_PREFIX_LEN
]
=
0
;
return
name
;
}
/* Output the static subroutine information block for the current
function. */
static
void
unicosmk_output_ssib
(
file
,
fnname
)
FILE
*
file
;
const
char
*
fnname
;
{
int
len
;
int
i
;
rtx
x
;
rtx
ciw
;
struct
machine_function
*
machine
=
cfun
->
machine
;
ssib_section
();
fprintf
(
file
,
"
\t
.endp
\n\n\t
.psect
\t
%s%s,data
\n
"
,
user_label_prefix
,
unicosmk_ssib_name
());
/* Some required stuff and the function name length. */
len
=
strlen
(
fnname
);
fprintf
(
file
,
"
\t
.quad
\t
^X20008%2.2X28
\n
"
,
len
);
/* Saved registers
??? We don't do that yet. */
fputs
(
"
\t
.quad
\t
0
\n
"
,
file
);
/* Function address. */
fputs
(
"
\t
.quad
\t
"
,
file
);
assemble_name
(
file
,
fnname
);
putc
(
'\n'
,
file
);
fputs
(
"
\t
.quad
\t
0
\n
"
,
file
);
fputs
(
"
\t
.quad
\t
0
\n
"
,
file
);
/* Function name.
??? We do it the same way Cray CC does it but this could be
simplified. */
for
(
i
=
0
;
i
<
len
;
i
++
)
fprintf
(
file
,
"
\t
.byte
\t
%d
\n
"
,
(
int
)(
fnname
[
i
]));
if
(
(
len
%
8
)
==
0
)
fputs
(
"
\t
.quad
\t
0
\n
"
,
file
);
else
fprintf
(
file
,
"
\t
.bits
\t
%d : 0
\n
"
,
(
8
-
(
len
%
8
))
*
8
);
/* All call information words used in the function. */
for
(
x
=
machine
->
first_ciw
;
x
;
x
=
XEXP
(
x
,
1
))
{
ciw
=
XEXP
(
x
,
0
);
fprintf
(
file
,
"
\t
.quad
\t
"
);
#if HOST_BITS_PER_WIDE_INT == 32
fprintf
(
file
,
HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
CONST_DOUBLE_HIGH
(
ciw
),
CONST_DOUBLE_LOW
(
ciw
));
#else
fprintf
(
file
,
HOST_WIDE_INT_PRINT_HEX
,
INTVAL
(
ciw
));
#endif
fprintf
(
file
,
"
\n
"
);
}
}
/* Add a call information word (CIW) to the list of the current function's
CIWs and return its index.
X is a CONST_INT or CONST_DOUBLE representing the CIW. */
rtx
unicosmk_add_call_info_word
(
x
)
rtx
x
;
{
rtx
node
;
struct
machine_function
*
machine
=
cfun
->
machine
;
node
=
gen_rtx_EXPR_LIST
(
VOIDmode
,
x
,
NULL_RTX
);
if
(
machine
->
first_ciw
==
NULL_RTX
)
machine
->
first_ciw
=
node
;
else
XEXP
(
machine
->
last_ciw
,
1
)
=
node
;
machine
->
last_ciw
=
node
;
++
machine
->
ciw_count
;
return
GEN_INT
(
machine
->
ciw_count
+
strlen
(
current_function_name
)
/
8
+
5
);
}
static
char
unicosmk_section_buf
[
100
];
char
*
unicosmk_text_section
()
{
static
int
count
=
0
;
sprintf
(
unicosmk_section_buf
,
"
\t
.endp
\n\n\t
.psect
\t
gcc@text___%d,code"
,
count
++
);
return
unicosmk_section_buf
;
}
char
*
unicosmk_data_section
()
{
static
int
count
=
1
;
sprintf
(
unicosmk_section_buf
,
"
\t
.endp
\n\n\t
.psect
\t
gcc@data___%d,data"
,
count
++
);
return
unicosmk_section_buf
;
}
/* The Cray assembler doesn't accept extern declarations for symbols which
are defined in the same file. We have to keep track of all global
symbols which are referenced and/or defined in a source file and output
extern declarations for those which are referenced but not defined at
the end of file. */
/* List of identifiers for which an extern declaration might have to be
emitted. */
struct
unicosmk_extern_list
{
struct
unicosmk_extern_list
*
next
;
const
char
*
name
;
};
static
struct
unicosmk_extern_list
*
unicosmk_extern_head
=
0
;
/* Output extern declarations which are required for every asm file. */
static
void
unicosmk_output_default_externs
(
file
)
FILE
*
file
;
{
static
const
char
*
externs
[]
=
{
"__T3E_MISMATCH"
};
int
i
;
int
n
;
n
=
ARRAY_SIZE
(
externs
);
for
(
i
=
0
;
i
<
n
;
i
++
)
fprintf
(
file
,
"
\t
.extern
\t
%s
\n
"
,
externs
[
i
]);
}
/* Output extern declarations for global symbols which are have been
referenced but not defined. */
static
void
unicosmk_output_externs
(
file
)
FILE
*
file
;
{
struct
unicosmk_extern_list
*
p
;
const
char
*
real_name
;
int
len
;
tree
name_tree
;
len
=
strlen
(
user_label_prefix
);
for
(
p
=
unicosmk_extern_head
;
p
!=
0
;
p
=
p
->
next
)
{
/* We have to strip the encoding and possibly remove user_label_prefix
from the identifier in order to handle -fleading-underscore and
explicit asm names correctly (cf. gcc.dg/asm-names-1.c). */
STRIP_NAME_ENCODING
(
real_name
,
p
->
name
);
if
(
len
&&
p
->
name
[
0
]
==
'*'
&&
!
memcmp
(
real_name
,
user_label_prefix
,
len
))
real_name
+=
len
;
name_tree
=
get_identifier
(
real_name
);
if
(
!
TREE_ASM_WRITTEN
(
name_tree
))
{
TREE_ASM_WRITTEN
(
name_tree
)
=
1
;
fputs
(
"
\t
.extern
\t
"
,
file
);
assemble_name
(
file
,
p
->
name
);
putc
(
'\n'
,
file
);
}
}
}
/* Record an extern. */
void
unicosmk_add_extern
(
name
)
const
char
*
name
;
{
struct
unicosmk_extern_list
*
p
;
p
=
(
struct
unicosmk_extern_list
*
)
permalloc
(
sizeof
(
struct
unicosmk_extern_list
));
p
->
next
=
unicosmk_extern_head
;
p
->
name
=
name
;
unicosmk_extern_head
=
p
;
}
/* The Cray assembler generates incorrect code if identifiers which
conflict with register names are used as instruction operands. We have
to replace such identifiers with DEX expressions. */
/* Structure to collect identifiers which have been replaced by DEX
expressions. */
struct
unicosmk_dex
{
struct
unicosmk_dex
*
next
;
const
char
*
name
;
};
/* List of identifiers which have been replaced by DEX expressions. The DEX
number is determined by the position in the list. */
static
struct
unicosmk_dex
*
unicosmk_dex_list
=
NULL
;
/* The number of elements in the DEX list. */
static
int
unicosmk_dex_count
=
0
;
/* Check if NAME must be replaced by a DEX expression. */
static
int
unicosmk_special_name
(
name
)
const
char
*
name
;
{
if
(
name
[
0
]
==
'*'
)
++
name
;
if
(
name
[
0
]
==
'$'
)
++
name
;
if
(
name
[
0
]
!=
'r'
&&
name
[
0
]
!=
'f'
&&
name
[
0
]
!=
'R'
&&
name
[
0
]
!=
'F'
)
return
0
;
switch
(
name
[
1
])
{
case
'1'
:
case
'2'
:
return
(
name
[
2
]
==
'\0'
||
(
ISDIGIT
(
name
[
2
])
&&
name
[
3
]
==
'\0'
));
case
'3'
:
return
(
name
[
2
]
==
'\0'
||
((
name
[
2
]
==
'0'
||
name
[
2
]
==
'1'
)
&&
name
[
3
]
==
'\0'
));
default
:
return
(
ISDIGIT
(
name
[
1
])
&&
name
[
2
]
==
'\0'
);
}
}
/* Return the DEX number if X must be replaced by a DEX expression and 0
otherwise. */
static
int
unicosmk_need_dex
(
x
)
rtx
x
;
{
struct
unicosmk_dex
*
dex
;
const
char
*
name
;
int
i
;
if
(
GET_CODE
(
x
)
!=
SYMBOL_REF
)
return
0
;
name
=
XSTR
(
x
,
0
);
if
(
!
unicosmk_special_name
(
name
))
return
0
;
i
=
unicosmk_dex_count
;
for
(
dex
=
unicosmk_dex_list
;
dex
;
dex
=
dex
->
next
)
{
if
(
!
strcmp
(
name
,
dex
->
name
))
return
i
;
--
i
;
}
dex
=
(
struct
unicosmk_dex
*
)
permalloc
(
sizeof
(
struct
unicosmk_dex
));
dex
->
name
=
name
;
dex
->
next
=
unicosmk_dex_list
;
unicosmk_dex_list
=
dex
;
++
unicosmk_dex_count
;
return
unicosmk_dex_count
;
}
/* Output the DEX definitions for this file. */
static
void
unicosmk_output_dex
(
file
)
FILE
*
file
;
{
struct
unicosmk_dex
*
dex
;
int
i
;
if
(
unicosmk_dex_list
==
NULL
)
return
;
fprintf
(
file
,
"
\t
.dexstart
\n
"
);
i
=
unicosmk_dex_count
;
for
(
dex
=
unicosmk_dex_list
;
dex
;
dex
=
dex
->
next
)
{
fprintf
(
file
,
"
\t
DEX (%d) = "
,
i
);
assemble_name
(
file
,
dex
->
name
);
putc
(
'\n'
,
file
);
--
i
;
}
fprintf
(
file
,
"
\t
.dexend
\n
"
);
}
#else
static
void
unicosmk_output_deferred_case_vectors
(
file
)
FILE
*
file
ATTRIBUTE_UNUSED
;
{}
static
void
unicosmk_gen_dsib
(
imaskP
)
unsigned
long
*
imaskP
ATTRIBUTE_UNUSED
;
{}
static
void
unicosmk_output_ssib
(
file
,
fnname
)
FILE
*
file
ATTRIBUTE_UNUSED
;
const
char
*
fnname
ATTRIBUTE_UNUSED
;
{}
rtx
unicosmk_add_call_info_word
(
x
)
rtx
x
ATTRIBUTE_UNUSED
;
{
return
NULL_RTX
;
}
static
int
unicosmk_need_dex
(
x
)
rtx
x
ATTRIBUTE_UNUSED
;
{
return
0
;
}
#endif
/* TARGET_ABI_UNICOSMK */
gcc/config/alpha/alpha.h
View file @
30102605
...
...
@@ -179,11 +179,17 @@ extern enum alpha_fp_trap_mode alpha_fptm;
/* These are for target os support and cannot be changed at runtime. */
#define TARGET_ABI_WINDOWS_NT 0
#define TARGET_ABI_OPEN_VMS 0
#define TARGET_ABI_OSF (!TARGET_ABI_WINDOWS_NT && !TARGET_ABI_OPEN_VMS)
#define TARGET_ABI_UNICOSMK 0
#define TARGET_ABI_OSF (!TARGET_ABI_WINDOWS_NT \
&& !TARGET_ABI_OPEN_VMS \
&& !TARGET_ABI_UNICOSMK)
#ifndef TARGET_AS_CAN_SUBTRACT_LABELS
#define TARGET_AS_CAN_SUBTRACT_LABELS TARGET_GAS
#endif
#ifndef TARGET_AS_SLASH_BEFORE_SUFFIX
#define TARGET_AS_SLASH_BEFORE_SUFFIX TARGET_GAS
#endif
#ifndef TARGET_CAN_FAULT_IN_PROLOGUE
#define TARGET_CAN_FAULT_IN_PROLOGUE 0
#endif
...
...
@@ -792,7 +798,9 @@ enum reg_class { NO_REGS, PV_REG, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
`R' is a SYMBOL_REF that has SYMBOL_REF_FLAG set or is the current
function.
'S' is a 6-bit constant (valid for a shift insn). */
'S' is a 6-bit constant (valid for a shift insn).
'U' is a symbolic operand. */
#define EXTRA_CONSTRAINT(OP, C) \
((C) == 'Q' ? normal_memory_operand (OP, VOIDmode) \
...
...
@@ -800,6 +808,8 @@ enum reg_class { NO_REGS, PV_REG, GENERAL_REGS, FLOAT_REGS, ALL_REGS,
: (C) == 'S' ? (GET_CODE (OP) == CONST_INT \
&& (unsigned HOST_WIDE_INT) INTVAL (OP) < 64) \
: (C) == 'T' ? GET_CODE (OP) == HIGH \
: (TARGET_ABI_UNICOSMK && (C) == 'U') \
? symbolic_operand (OP, VOIDmode) \
: 0)
/* Given an rtx X being reloaded into a reg required to be
...
...
@@ -2174,7 +2184,8 @@ do { \
{"hard_int_register_operand", {SUBREG, REG}}, \
{"reg_not_elim_operand", {SUBREG, REG}}, \
{"reg_no_subreg_operand", {REG}}, \
{"addition_operation", {PLUS}},
{"addition_operation", {PLUS}}, \
{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST}},
/* Define the `__builtin_va_list' type for the ABI. */
#define BUILD_VA_LIST_TYPE(VALIST) \
...
...
gcc/config/alpha/alpha.md
View file @
30102605
...
...
@@ -31,6 +31,10 @@
(UNSPEC_MSKXH 3)
(UNSPEC_CVTQL 4)
(UNSPEC_NT_LDA 5)
(UNSPEC_UMK_LAUM 6)
(UNSPEC_UMK_LALM 7)
(UNSPEC_UMK_LAL 8)
(UNSPEC_UMK_LOAD_CIW 9)
])
;; UNSPEC_VOLATILE:
...
...
@@ -50,6 +54,12 @@
(UNSPECV_FORCE_MOV 11)
])
;; Where necessary, the suffixes _le and _be are used to distinguish between
;; little-endian and big-endian patterns.
;;
;; Note that the Unicos/Mk assembler does not support the following
;; opcodes: mov, fmov, nop, fnop, unop.
;; Processor type -- this attribute must exactly match the processor_type
;; enumeration in alpha.h.
...
...
@@ -904,11 +914,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
""
"subqv %r1,%2,%0")
;; The Unicos/Mk assembler doesn't support mull.
(define_insn "mulsi3"
[
(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
(match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
""
"
!TARGET_ABI_UNICOSMK
"
"mull %r1,%2,%0"
[
(set_attr "type" "imul")
(set_attr "opsize" "si")])
...
...
@@ -918,7 +930,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(sign_extend:DI
(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
(match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
""
"
!TARGET_ABI_UNICOSMK
"
"mull %r1,%2,%0"
[
(set_attr "type" "imul")
(set_attr "opsize" "si")])
...
...
@@ -932,7 +944,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(sign_extend:DI (mult:SI (match_dup 1)
(match_dup 2))))
(const_int 0))]
""
"
!TARGET_ABI_UNICOSMK
"
"mullv %r1,%2,%0"
[
(set_attr "type" "imul")
(set_attr "opsize" "si")])
...
...
@@ -984,14 +996,17 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
[
(set_attr "type" "imul")
(set_attr "opsize" "udi")])
;; The divide and remainder operations always take their inputs from
;; r24 and r25, put their output in r27, and clobber r23 and r28.
;; The divide and remainder operations take their inputs from r24 and
;; r25, put their output in r27, and clobber r23 and r28 on all
;; systems except Unicos/Mk. On Unicos, the standard library provides
;; subroutines which use the standard calling convention and work on
;; DImode operands.
;; ??? Force sign-extension here because some versions of OSF/1
don't
;;
do the right thing if the inputs are not properly sign-extended.
;;
But Linux, for instance, does not have this problem. Is it worth
;;
the complication here to eliminate the sign extension?
;;
Interix/NT has the same sign-extension problem.
;; ??? Force sign-extension here because some versions of OSF/1
and
;;
Interix/NT don't do the right thing if the inputs are not properly
;;
sign-extended. But Linux, for instance, does not have this
;;
problem. Is it worth the complication here to eliminate the sign
;;
extension?
(define_expand "divsi3"
[
(set (reg:DI 24)
...
...
@@ -1004,7 +1019,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(clobber (reg:DI 28))])
(set (match_operand:SI 0 "nonimmediate_operand" "")
(subreg:SI (reg:DI 27) 0))]
"! TARGET_ABI_OPEN_VMS"
"! TARGET_ABI_OPEN_VMS
&& ! TARGET_ABI_UNICOSMK
"
"")
(define_expand "udivsi3"
...
...
@@ -1018,7 +1033,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(clobber (reg:DI 28))])
(set (match_operand:SI 0 "nonimmediate_operand" "")
(subreg:SI (reg:DI 27) 0))]
"! TARGET_ABI_OPEN_VMS"
"! TARGET_ABI_OPEN_VMS
&& ! TARGET_ABI_UNICOSMK
"
"")
(define_expand "modsi3"
...
...
@@ -1032,7 +1047,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(clobber (reg:DI 28))])
(set (match_operand:SI 0 "nonimmediate_operand" "")
(subreg:SI (reg:DI 27) 0))]
"! TARGET_ABI_OPEN_VMS"
"! TARGET_ABI_OPEN_VMS
&& ! TARGET_ABI_UNICOSMK
"
"")
(define_expand "umodsi3"
...
...
@@ -1046,7 +1061,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(clobber (reg:DI 28))])
(set (match_operand:SI 0 "nonimmediate_operand" "")
(subreg:SI (reg:DI 27) 0))]
"! TARGET_ABI_OPEN_VMS"
"! TARGET_ABI_OPEN_VMS
&& ! TARGET_ABI_UNICOSMK
"
"")
(define_expand "divdi3"
...
...
@@ -1059,7 +1074,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(clobber (reg:DI 28))])
(set (match_operand:DI 0 "nonimmediate_operand" "")
(reg:DI 27))]
"! TARGET_ABI_OPEN_VMS"
"! TARGET_ABI_OPEN_VMS
&& ! TARGET_ABI_UNICOSMK
"
"")
(define_expand "udivdi3"
...
...
@@ -1072,10 +1087,23 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(clobber (reg:DI 28))])
(set (match_operand:DI 0 "nonimmediate_operand" "")
(reg:DI 27))]
"! TARGET_ABI_OPEN_VMS"
"! TARGET_ABI_OPEN_VMS
&& ! TARGET_ABI_UNICOSMK
"
"")
(define_expand "moddi3"
[
(use (match_operand:DI 0 "nonimmediate_operand" ""))
(use (match_operand:DI 1 "input_operand" ""))
(use (match_operand:DI 2 "input_operand" ""))]
"!TARGET_ABI_OPEN_VMS"
{
if (TARGET_ABI_UNICOSMK)
emit_insn (gen_moddi3_umk (operands
[
0
]
, operands
[
1
]
, operands
[
2
]
));
else
emit_insn (gen_moddi3_dft (operands
[
0
]
, operands
[
1
]
, operands
[
2
]
));
DONE;
})
(define_expand "moddi3_dft"
[
(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
(set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
(parallel
[
(set (reg:DI 27)
...
...
@@ -1085,10 +1113,48 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(clobber (reg:DI 28))])
(set (match_operand:DI 0 "nonimmediate_operand" "")
(reg:DI 27))]
"! TARGET_ABI_OPEN_VMS"
"! TARGET_ABI_OPEN_VMS
&& ! TARGET_ABI_UNICOSMK
"
"")
;; On Unicos/Mk, we do as the system's C compiler does:
;; compute the quotient, multiply and subtract.
(define_expand "moddi3_umk"
[
(use (match_operand:DI 0 "nonimmediate_operand" ""))
(use (match_operand:DI 1 "input_operand" ""))
(use (match_operand:DI 2 "input_operand" ""))]
"TARGET_ABI_UNICOSMK"
{
rtx mul, div, tmp;
mul = gen_reg_rtx (DImode);
tmp = gen_reg_rtx (DImode);
operands
[
1
]
= force_reg (DImode, operands
[
1
]
);
operands
[
2
]
= force_reg (DImode, operands
[
2
]
);
div = expand_binop (DImode, sdiv_optab, operands
[
1
]
, operands
[
2
]
,
NULL_RTX, 0, OPTAB_LIB);
div = force_reg (DImode, div);
emit_insn (gen_muldi3 (mul, operands
[
2
]
, div));
emit_insn (gen_subdi3 (tmp, operands
[
1
]
, mul));
emit_move_insn (operands
[
0
]
, tmp);
DONE;
})
(define_expand "umoddi3"
[
(use (match_operand:DI 0 "nonimmediate_operand" ""))
(use (match_operand:DI 1 "input_operand" ""))
(use (match_operand:DI 2 "input_operand" ""))]
"! TARGET_ABI_OPEN_VMS"
{
if (TARGET_ABI_UNICOSMK)
emit_insn (gen_umoddi3_umk (operands
[
0
]
, operands
[
1
]
, operands
[
2
]
));
else
emit_insn (gen_umoddi3_dft (operands
[
0
]
, operands
[
1
]
, operands
[
2
]
));
DONE;
})
(define_expand "umoddi3_dft"
[
(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
(set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
(parallel
[
(set (reg:DI 27)
...
...
@@ -1098,9 +1164,31 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(clobber (reg:DI 28))])
(set (match_operand:DI 0 "nonimmediate_operand" "")
(reg:DI 27))]
"! TARGET_ABI_OPEN_VMS"
"! TARGET_ABI_OPEN_VMS
&& ! TARGET_ABI_UNICOSMK
"
"")
(define_expand "umoddi3_umk"
[
(use (match_operand:DI 0 "nonimmediate_operand" ""))
(use (match_operand:DI 1 "input_operand" ""))
(use (match_operand:DI 2 "input_operand" ""))]
"TARGET_ABI_UNICOSMK"
{
rtx mul, div, tmp;
mul = gen_reg_rtx (DImode);
tmp = gen_reg_rtx (DImode);
operands
[
1
]
= force_reg (DImode, operands
[
1
]
);
operands
[
2
]
= force_reg (DImode, operands
[
2
]
);
div = expand_binop (DImode, udiv_optab, operands
[
1
]
, operands
[
2
]
,
NULL_RTX, 1, OPTAB_LIB);
div = force_reg (DImode, div);
emit_insn (gen_muldi3 (mul, operands
[
2
]
, div));
emit_insn (gen_subdi3 (tmp, operands
[
1
]
, mul));
emit_move_insn (operands
[
0
]
, tmp);
DONE;
})
;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
;; expanded by the assembler.
...
...
@@ -1121,7 +1209,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
[
(reg:DI 24) (reg:DI 25)
]
)))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
"! TARGET_ABI_OPEN_VMS"
"! TARGET_ABI_OPEN_VMS
&& ! TARGET_ABI_UNICOSMK
"
"%E0 $24,$25,$27"
[
(set_attr "type" "jsr")
(set_attr "length" "8")])
...
...
@@ -1143,7 +1231,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
[
(reg:DI 24) (reg:DI 25)
]
))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
"! TARGET_ABI_OPEN_VMS"
"! TARGET_ABI_OPEN_VMS
&& ! TARGET_ABI_UNICOSMK
"
"%E0 $24,$25,$27"
[
(set_attr "type" "jsr")
(set_attr "length" "8")])
...
...
@@ -1655,6 +1743,18 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
;;
;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
(define_expand "unaligned_extendqidi"
[
(use (match_operand:QI 0 "register_operand" ""))
(use (match_operand:DI 1 "address_operand" ""))]
""
{
if (WORDS_BIG_ENDIAN)
emit_insn (gen_unaligned_extendqidi_be (operands
[
0
]
, operands
[
1
]
));
else
emit_insn (gen_unaligned_extendqidi_le (operands
[
0
]
, operands
[
1
]
));
DONE;
})
(define_expand "unaligned_extendqidi_le"
[
(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
(set (match_dup 3)
(mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
...
...
@@ -1667,14 +1767,51 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(const_int 3)))))
(set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
(ashiftrt:DI (match_dup 4) (const_int 56)))]
""
"
! WORDS_BIG_ENDIAN
"
{
operands
[
2
]
= gen_reg_rtx (DImode);
operands
[
3
]
= gen_reg_rtx (DImode);
operands
[
4
]
= gen_reg_rtx (DImode);
})
(define_expand "unaligned_extendqidi_be"
[
(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
(set (match_dup 3) (plus:DI (match_dup 2) (const_int -1)))
(set (match_dup 4)
(mem:DI (and:DI (match_dup 3)
(const_int -8))))
(set (match_dup 5) (plus:DI (match_dup 2) (const_int -2)))
(set (match_dup 6)
(ashift:DI (match_dup 4)
(ashift:DI
(and:DI
(plus:DI (match_dup 5) (const_int 1))
(const_int 7))
(const_int 3))))
(set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
(ashiftrt:DI (match_dup 6) (const_int 56)))]
"WORDS_BIG_ENDIAN"
{
operands
[
2
]
= gen_reg_rtx (DImode);
operands
[
3
]
= gen_reg_rtx (DImode);
operands
[
4
]
= gen_reg_rtx (DImode);
operands
[
5
]
= gen_reg_rtx (DImode);
operands
[
6
]
= gen_reg_rtx (DImode);
})
(define_expand "unaligned_extendhidi"
[
(use (match_operand:QI 0 "register_operand" ""))
(use (match_operand:DI 1 "address_operand" ""))]
""
{
if (WORDS_BIG_ENDIAN)
emit_insn (gen_unaligned_extendhidi_be (operands
[
0
]
, operands
[
1
]
));
else
emit_insn (gen_unaligned_extendhidi_le (operands
[
0
]
, operands
[
1
]
));
DONE;
})
(define_expand "unaligned_extendhidi_le"
[
(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
(set (match_dup 3)
(mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
...
...
@@ -1687,13 +1824,36 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(const_int 3)))))
(set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
(ashiftrt:DI (match_dup 4) (const_int 48)))]
""
"
! WORDS_BIG_ENDIAN
"
{
operands
[
2
]
= gen_reg_rtx (DImode);
operands
[
3
]
= gen_reg_rtx (DImode);
operands
[
4
]
= gen_reg_rtx (DImode);
})
(define_expand "unaligned_extendhidi_be"
[
(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
(set (match_dup 3) (plus:DI (match_dup 2) (const_int -2)))
(set (match_dup 4)
(mem:DI (and:DI (match_dup 3)
(const_int -8))))
(set (match_dup 5) (plus:DI (match_dup 2) (const_int -3)))
(set (match_dup 6)
(ashift:DI (match_dup 4)
(ashift:DI
(and:DI (match_dup 5) (const_int 7))
(const_int 8))))
(set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
(ashiftrt:DI (match_dup 6) (const_int 48)))]
"WORDS_BIG_ENDIAN"
{
operands
[
2
]
= gen_reg_rtx (DImode);
operands
[
3
]
= gen_reg_rtx (DImode);
operands
[
4
]
= gen_reg_rtx (DImode);
operands
[
5
]
= gen_reg_rtx (DImode);
operands
[
6
]
= gen_reg_rtx (DImode);
})
(define_insn "
*
extxl_const"
[
(set (match_operand:DI 0 "register_operand" "=r")
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
...
...
@@ -1703,13 +1863,26 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
"ext%M2l %r1,%s3,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "extxl"
(define_insn "extxl
_le
"
[
(set (match_operand:DI 0 "register_operand" "=r")
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(match_operand:DI 2 "mode_width_operand" "n")
(ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
(const_int 3))))]
""
"! WORDS_BIG_ENDIAN"
"ext%M2l %r1,%3,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "extxl_be"
[
(set (match_operand:DI 0 "register_operand" "=r")
(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(match_operand:DI 2 "mode_width_operand" "n")
(minus:DI
(const_int 56)
(ashift:DI
(match_operand:DI 3 "reg_or_8bit_operand" "rI")
(const_int 3)))))]
"WORDS_BIG_ENDIAN"
"ext%M2l %r1,%3,%0"
[
(set_attr "type" "shift")
]
)
...
...
@@ -1717,26 +1890,50 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
;; in shifts larger than a word size. So capture these patterns that it
;; should have turned into zero_extracts.
(define_insn "
*
extxl_1"
(define_insn "
*
extxl_1
_le
"
[
(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3)))
(match_operand:DI 3 "mode_mask_operand" "n")))]
""
"
! WORDS_BIG_ENDIAN
"
"ext%U3l %1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "
*
extql_2"
(define_insn "
*
extxl_1_be"
[
(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (lshiftrt:DI
(match_operand:DI 1 "reg_or_0_operand" "rJ")
(minus:DI (const_int 56)
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))
(match_operand:DI 3 "mode_mask_operand" "n")))]
"WORDS_BIG_ENDIAN"
"ext%U3l %1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "
*
extql_2_le"
[
(set (match_operand:DI 0 "register_operand" "=r")
(lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
""
"! WORDS_BIG_ENDIAN"
"extql %1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "
*
extql_2_be"
[
(set (match_operand:DI 0 "register_operand" "=r")
(lshiftrt:DI
(match_operand:DI 1 "reg_or_0_operand" "rJ")
(minus:DI (const_int 56)
(ashift:DI
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3)))))]
"WORDS_BIG_ENDIAN"
"extql %1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "extqh"
(define_insn "extqh
_le
"
[
(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(match_operand:DI 1 "reg_or_0_operand" "rJ")
...
...
@@ -1746,11 +1943,25 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 7))
(const_int 3)))))]
""
"! WORDS_BIG_ENDIAN"
"extqh %r1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "extqh_be"
[
(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(match_operand:DI 1 "reg_or_0_operand" "rJ")
(ashift:DI
(and:DI
(plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 1))
(const_int 7))
(const_int 3))))]
"WORDS_BIG_ENDIAN"
"extqh %r1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "extlh"
(define_insn "extlh
_le
"
[
(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
...
...
@@ -1761,11 +1972,28 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 7))
(const_int 3)))))]
""
"
! WORDS_BIG_ENDIAN
"
"extlh %r1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "extwh"
(define_insn "extlh_be"
[
(set (match_operand:DI 0 "register_operand" "=r")
(and:DI
(ashift:DI
(match_operand:DI 1 "reg_or_0_operand" "rJ")
(ashift:DI
(and:DI
(plus:DI
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 1))
(const_int 7))
(const_int 3)))
(const_int 2147483647)))]
"WORDS_BIG_ENDIAN"
"extlh %r1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "extwh_le"
[
(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
...
...
@@ -1776,7 +2004,23 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 7))
(const_int 3)))))]
""
"! WORDS_BIG_ENDIAN"
"extwh %r1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "extwh_be"
[
(set (match_operand:DI 0 "register_operand" "=r")
(and:DI
(ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
(ashift:DI
(and:DI
(plus:DI
(match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 1))
(const_int 7))
(const_int 3)))
(const_int 65535)))]
"WORDS_BIG_ENDIAN"
"extwh %r1,%2,%0"
[
(set_attr "type" "shift")
]
)
...
...
@@ -1830,39 +2074,79 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
"insll %1,%s2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "insbl"
(define_insn "insbl
_le
"
[
(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
""
"
! WORDS_BIG_ENDIAN
"
"insbl %1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "inswl"
(define_insn "insbl_be"
[
(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
(minus:DI (const_int 56)
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3)))))]
"WORDS_BIG_ENDIAN"
"insbl %1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "inswl_le"
[
(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
""
"
! WORDS_BIG_ENDIAN
"
"inswl %1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "insll"
(define_insn "inswl_be"
[
(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
(minus:DI (const_int 56)
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3)))))]
"WORDS_BIG_ENDIAN"
"inswl %1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "insll_le"
[
(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
""
"! WORDS_BIG_ENDIAN"
"insll %1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "insll_be"
[
(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
(minus:DI (const_int 56)
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3)))))]
"WORDS_BIG_ENDIAN"
"insll %1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "insql"
(define_insn "insql
_le
"
[
(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (match_operand:DI 1 "register_operand" "r")
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
""
"! WORDS_BIG_ENDIAN"
"insql %1,%2,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "insql_be"
[
(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (match_operand:DI 1 "register_operand" "r")
(minus:DI (const_int 56)
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3)))))]
"WORDS_BIG_ENDIAN"
"insql %1,%2,%0"
[
(set_attr "type" "shift")
]
)
...
...
@@ -1913,7 +2197,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
"ins%M2h %1,%3,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "mskxl"
(define_insn "mskxl
_le
"
[
(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (not:DI (ashift:DI
(match_operand:DI 2 "mode_mask_operand" "n")
...
...
@@ -1921,7 +2205,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(match_operand:DI 3 "reg_or_8bit_operand" "rI")
(const_int 3))))
(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
""
"! WORDS_BIG_ENDIAN"
"msk%U2l %r1,%3,%0"
[
(set_attr "type" "shift")
]
)
(define_insn "mskxl_be"
[
(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (not:DI (ashift:DI
(match_operand:DI 2 "mode_mask_operand" "n")
(minus:DI (const_int 56)
(ashift:DI
(match_operand:DI 3 "reg_or_8bit_operand" "rI")
(const_int 3)))))
(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
"WORDS_BIG_ENDIAN"
"msk%U2l %r1,%3,%0"
[
(set_attr "type" "shift")
]
)
...
...
@@ -2328,6 +2625,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
operands
[
1
]
= force_reg (SFmode, operands
[
1
]
);
})
;; The Unicos/Mk assembler doesn't support cvtst, but we've already
;; asserted that alpha_fptm == ALPHA_FPTM_N.
(define_insn "
*
extendsfdf2_ieee"
[
(set (match_operand:DF 0 "register_operand" "=&f")
(float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
...
...
@@ -2341,7 +2641,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
"@
fmov
%1,%0
cpys %1,
%1,%0
ld%, %0,%1
st%- %1,%0"
[
(set_attr "type" "fcpys,fld,fst")
]
)
...
...
@@ -4164,6 +4464,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
;; work differently, so we have different patterns for each.
;; On Unicos/Mk a call information word (CIW) must be generated for each
;; call. The CIW contains information about arguments passed in registers
;; and is stored in the caller's SSIB. Its offset relative to the beginning
;; of the SSIB is passed in $25. Handling this properly is quite complicated
;; in the presence of inlining since the CIWs for calls performed by the
;; inlined function must be stored in the SSIB of the function it is inlined
;; into as well. We encode the CIW in an unspec and append it to the list
;; of the CIWs for the current function only when the instruction for loading
;; $25 is generated.
(define_expand "call"
[
(use (match_operand:DI 0 "" ""))
(use (match_operand 1 "" ""))
...
...
@@ -4175,6 +4485,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
emit_call_insn (gen_call_nt (operands
[
0
]
, operands
[
1
]
));
else if (TARGET_ABI_OPEN_VMS)
emit_call_insn (gen_call_vms (operands
[
0
]
, operands
[
2
]
));
else if (TARGET_ABI_UNICOSMK)
emit_call_insn (gen_call_umk (operands
[
0
]
, operands
[
2
]
));
else
emit_call_insn (gen_call_osf (operands
[
0
]
, operands
[
1
]
));
DONE;
...
...
@@ -4225,6 +4537,30 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
operands
[
0
]
= force_reg (DImode, operands
[
0
]
);
})
;; Calls on Unicos/Mk are always indirect.
;; op 0: symbol ref for called function
;; op 1: CIW for $25 represented by an unspec
(define_expand "call_umk"
[
(parallel
[
(call (mem:DI (match_operand 0 "" ""))
(match_operand 1 "" ""))
(use (reg:DI 25))
(clobber (reg:DI 26))])]
""
{
if (GET_CODE (operands
[
0
]
) != MEM)
abort ();
/
*
Always load the address of the called function into a register;
load the CIW in $25.
*
/
operands
[
0
]
= XEXP (operands
[
0
]
, 0);
if (GET_CODE (operands
[
0
]
) != REG)
operands
[
0
]
= force_reg (DImode, operands
[
0
]
);
emit_move_insn (gen_rtx_REG (DImode, 25), operands
[
1
]
);
})
;;
;; call openvms/alpha
;; op 0: symbol ref for called function
...
...
@@ -4279,6 +4615,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
else if (TARGET_ABI_OPEN_VMS)
emit_call_insn (gen_call_value_vms (operands
[
0
]
, operands
[
1
]
,
operands
[
3
]
));
else if (TARGET_ABI_UNICOSMK)
emit_call_insn (gen_call_value_umk (operands
[
0
]
, operands
[
1
]
,
operands
[
3
]
));
else
emit_call_insn (gen_call_value_osf (operands
[
0
]
, operands
[
1
]
,
operands
[
2
]
));
...
...
@@ -4369,6 +4708,24 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
}
})
(define_expand "call_value_umk"
[
(parallel
[
(set (match_operand 0 "" "")
(call (mem:DI (match_operand 1 "" ""))
(match_operand 2 "" "")))
(use (reg:DI 25))
(clobber (reg:DI 26))])]
""
{
if (GET_CODE (operands
[
1
]
) != MEM)
abort ();
operands
[
1
]
= XEXP (operands
[
1
]
, 0);
if (GET_CODE (operands
[
1
]
) != REG)
operands
[
1
]
= force_reg (DImode, operands
[
1
]
);
emit_move_insn (gen_rtx_REG (DImode, 25), operands
[
2
]
);
})
(define_insn "
*
call_osf_1_er_noreturn"
[
(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,i"))
(match_operand 1 "" ""))
...
...
@@ -4455,6 +4812,15 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
[
(set_attr "type" "jsr")
(set_attr "length" "12,16")])
(define_insn "
*
call_umk_1"
[
(call (mem:DI (match_operand:DI 0 "call_operand" "r"))
(match_operand 1 "" ""))
(use (reg:DI 25))
(clobber (reg:DI 26))]
"TARGET_ABI_UNICOSMK"
"jsr $26,(%0)"
[
(set_attr "type" "jsr")
]
)
;; Call subroutine returning any type.
(define_expand "untyped_call"
...
...
@@ -4517,58 +4883,30 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
[
(set_attr "type" "ibr")
]
)
(define_expand "tablejump"
[
(use (match_operand:SI 0 "register_operand" ""))
(use (match_operand:SI 1 "" ""))]
[
(parallel
[
(set (pc)
(match_operand 0 "register_operand" ""))
(use (label_ref:DI (match_operand 1 "" "")))])]
""
{
if (TARGET_ABI_WINDOWS_NT)
emit_jump_insn (gen_tablejump_nt (operands
[
0
]
, operands
[
1
]
));
else if (TARGET_ABI_OPEN_VMS)
emit_jump_insn (gen_tablejump_vms (operands
[
0
]
, operands
[
1
]
));
else
emit_jump_insn (gen_tablejump_osf (operands
[
0
]
, operands
[
1
]
));
DONE;
{
rtx dest = gen_reg_rtx (DImode);
emit_insn (gen_extendsidi2 (dest, operands
[
0
]
));
operands
[
0
]
= dest;
}
else if (TARGET_ABI_OSF)
{
rtx dest = gen_reg_rtx (DImode);
emit_insn (gen_extendsidi2 (dest, operands
[
0
]
));
emit_insn (gen_adddi3 (dest, gen_rtx_REG (DImode, 29), dest));
operands
[
0
]
= dest;
}
})
(define_expand "tablejump_osf"
[
(set (match_dup 3)
(sign_extend:DI (match_operand:SI 0 "register_operand" "")))
(set (match_dup 3)
(plus:DI (reg:DI 29) (match_dup 3)))
(parallel
[
(set (pc)
(match_dup 3))
(use (label_ref (match_operand 1 "" "")))])]
""
{ operands
[
3
]
= gen_reg_rtx (DImode); })
(define_expand "tablejump_nt"
[
(set (match_dup 3)
(sign_extend:DI (match_operand:SI 0 "register_operand" "")))
(parallel
[
(set (pc)
(match_dup 3))
(use (label_ref (match_operand 1 "" "")))])]
""
{ operands
[
3
]
= gen_reg_rtx (DImode); })
;;
;; tablejump, openVMS way
;; op 0: offset
;; op 1: label preceding jump-table
;;
(define_expand "tablejump_vms"
[
(set (match_dup 2)
(match_operand:DI 0 "register_operand" ""))
(set (pc)
(plus:DI (match_dup 2)
(label_ref (match_operand 1 "" ""))))]
""
{ operands
[
2
]
= gen_reg_rtx (DImode); })
(define_insn "
*
tablejump_osf_nt_internal"
[
(set (pc)
(match_operand:DI 0 "register_operand" "r"))
(use (label_ref (match_operand 1 "" "")))]
(use (label_ref
:DI
(match_operand 1 "" "")))]
"(TARGET_ABI_OSF || TARGET_ABI_WINDOWS_NT)
&& alpha_tablejump_addr_vec (insn)"
{
...
...
@@ -4577,16 +4915,11 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
}
[
(set_attr "type" "ibr")
]
)
;;
;; op 0 is table offset
;; op 1 is table label
;;
(define_insn "
*
tablejump_vms_internal"
(define_insn "
*
tablejump_internal"
[
(set (pc)
(
plus (match_operand:DI 0 "register_operand" "r"
)
(label_ref (match_operand 1 "" "")
)))]
"
TARGET_ABI_OPEN_VMS
"
(
match_operand:DI 0 "register_operand" "r")
)
(use (label_ref (match_operand 1 "" ""
)))]
""
"jmp $31,(%0),0"
[
(set_attr "type" "ibr")
]
)
...
...
@@ -4613,9 +4946,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, SFmode)
|| reg_or_fp0_operand (operands
[
1
]
, SFmode))"
"@
fmov
%R1,%0
cpys %R1,
%R1,%0
ld%, %0,%1
mov
%r1,%0
bis $31,
%r1,%0
ldl %0,%1
st%, %R1,%0
stl %r1,%0"
...
...
@@ -4628,9 +4961,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, SFmode)
|| reg_or_fp0_operand (operands
[
1
]
, SFmode))"
"@
fmov
%R1,%0
cpys %R1,
%R1,%0
ld%, %0,%1
mov
%r1,%0
bis $31,
%r1,%0
ldl %0,%1
st%, %R1,%0
stl %r1,%0
...
...
@@ -4645,7 +4978,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, SFmode)
|| reg_or_fp0_operand (operands
[
1
]
, SFmode))"
"@
mov
%r1,%0
bis $31,
%r1,%0
ldl %0,%1
stl %r1,%0"
[
(set_attr "type" "ilog,ild,ist")
]
)
...
...
@@ -4657,9 +4990,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, DFmode)
|| reg_or_fp0_operand (operands
[
1
]
, DFmode))"
"@
fmov
%R1,%0
cpys %R1,
%R1,%0
ld%- %0,%1
mov
%r1,%0
bis $31,
%r1,%0
ldq %0,%1
st%- %R1,%0
stq %r1,%0"
...
...
@@ -4672,9 +5005,9 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, DFmode)
|| reg_or_fp0_operand (operands
[
1
]
, DFmode))"
"@
fmov
%R1,%0
cpys %R1,
%R1,%0
ld%- %0,%1
mov
%r1,%0
bis $31,
%r1,%0
ldq %0,%1
st%- %R1,%0
stq %r1,%0
...
...
@@ -4689,7 +5022,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, DFmode)
|| reg_or_fp0_operand (operands
[
1
]
, DFmode))"
"@
mov
%r1,%0
bis $31,
%r1,%0
ldq %0,%1
stq %r1,%0"
[
(set_attr "type" "ilog,ild,ist")
]
)
...
...
@@ -4749,16 +5082,16 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(define_insn "
*
movsi_nofix"
[
(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,
*f,*
f,m")
(match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,
*fJ,m,*
f"))]
"
TARGET_ABI_OSF
&& ! TARGET_FIX
"
(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK)
&& ! TARGET_FIX
&& (register_operand (operands
[
0
]
, SImode)
|| reg_or_0_operand (operands
[
1
]
, SImode))"
"@
mov
%r1,%0
bis $31,
%r1,%0
lda %0,%1($31)
ldah %0,%h1($31)
ldl %0,%1
stl %r1,%0
fmov
%R1,%0
cpys %R1,
%R1,%0
ld%, %0,%1
st%, %R1,%0"
[
(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")
]
)
...
...
@@ -4770,12 +5103,12 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, SImode)
|| reg_or_0_operand (operands
[
1
]
, SImode))"
"@
mov
%r1,%0
bis $31,
%r1,%0
lda %0,%1($31)
ldah %0,%h1($31)
ldl %0,%1
stl %r1,%0
fmov
%R1,%0
cpys %R1,
%R1,%0
ld%, %0,%1
st%, %R1,%0
ftois %1,%0
...
...
@@ -4789,13 +5122,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, SImode)
|| reg_or_0_operand (operands
[
1
]
, SImode))"
"@
mov
%1,%0
bis $31,
%1,%0
lda %0,%1
ldah %0,%h1
lda %0,%1
ldl %0,%1
stl %r1,%0
fmov
%R1,%0
cpys %R1,
%R1,%0
ld%, %0,%1
st%, %R1,%0"
[
(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")
]
)
...
...
@@ -4807,7 +5140,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, HImode)
|| register_operand (operands
[
1
]
, HImode))"
"@
mov
%r1,%0
bis $31,
%r1,%0
lda %0,%L1($31)"
[
(set_attr "type" "ilog,iadd")
]
)
...
...
@@ -4818,7 +5151,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, HImode)
|| reg_or_0_operand (operands
[
1
]
, HImode))"
"@
mov
%r1,%0
bis $31,
%r1,%0
lda %0,%L1($31)
ldwu %0,%1
stw %r1,%0"
...
...
@@ -4831,7 +5164,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, QImode)
|| register_operand (operands
[
1
]
, QImode))"
"@
mov
%r1,%0
bis $31,
%r1,%0
lda %0,%L1($31)"
[
(set_attr "type" "ilog,iadd")
]
)
...
...
@@ -4842,7 +5175,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, QImode)
|| reg_or_0_operand (operands
[
1
]
, QImode))"
"@
mov
%r1,%0
bis $31,
%r1,%0
lda %0,%L1($31)
ldbu %0,%1
stb %r1,%0"
...
...
@@ -4879,6 +5212,87 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
FAIL;
})
;; Split the load of an address into a four-insn sequence on Unicos/Mk.
;; Always generate a REG_EQUAL note for the last instruction to facilitate
;; optimisations. If the symbolic operand is a label_ref, generate REG_LABEL
;; notes and update LABEL_NUSES because this is not done automatically.
;; Labels may be incorrectly deleted if we don't do this.
;;
;; Describing what the individual instructions do correctly is too complicated
;; so use UNSPECs for each of the three parts of an address.
(define_split
[
(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "symbolic_operand" ""))]
"TARGET_ABI_UNICOSMK && reload_completed"
[
(const_int 0)
]
{
rtx insn1, insn2, insn3;
insn1 = emit_insn (gen_umk_laum (operands
[
0
]
, operands
[
1
]
));
emit_insn (gen_ashldi3 (operands
[
0
]
, operands
[
0
]
, GEN_INT (32)));
insn2 = emit_insn (gen_umk_lalm (operands
[
0
]
, operands
[
0
]
, operands
[
1
]
));
insn3 = emit_insn (gen_umk_lal (operands
[
0
]
, operands
[
0
]
, operands
[
1
]
));
REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_EQUAL, operands
[
1
]
,
REG_NOTES (insn3));
if (GET_CODE (operands
[
1
]
) == LABEL_REF)
{
rtx label;
label = XEXP (operands[1], 0);
REG_NOTES (insn1) = gen_rtx_EXPR_LIST (REG_LABEL, label,
REG_NOTES (insn1));
REG_NOTES (insn2) = gen_rtx_EXPR_LIST (REG_LABEL, label,
REG_NOTES (insn2));
REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_LABEL, label,
REG_NOTES (insn3));
LABEL_NUSES (label) += 3;
}
DONE;
})
;; Instructions for loading the three parts of an address on Unicos/Mk.
(define_insn "umk_laum"
[
(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI
[
(match_operand:DI 1 "symbolic_operand" "")
]
UNSPEC_UMK_LAUM))]
"TARGET_ABI_UNICOSMK"
"laum %r0,%t1($31)"
[
(set_attr "type" "iadd")
]
)
(define_insn "umk_lalm"
[
(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
(unspec:DI
[
(match_operand:DI 2 "symbolic_operand" "")
]
UNSPEC_UMK_LALM)))]
"TARGET_ABI_UNICOSMK"
"lalm %r0,%t2(%r1)"
[
(set_attr "type" "iadd")
]
)
(define_insn "umk_lal"
[
(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
(unspec:DI
[
(match_operand:DI 2 "symbolic_operand" "")
]
UNSPEC_UMK_LAL)))]
"TARGET_ABI_UNICOSMK"
"lal %r0,%t2(%r1)"
[
(set_attr "type" "iadd")
]
)
;; Add a new call information word to the current function's list of CIWs
;; and load its index into $25. Doing it here ensures that the CIW will be
;; associated with the correct function even in the presence of inlining.
(define_insn "
*
umk_load_ciw"
[
(set (reg:DI 25)
(unspec:DI
[
(match_operand 0 "" "")
]
UNSPEC_UMK_LOAD_CIW))]
"TARGET_ABI_UNICOSMK"
{
operands
[
0
]
= unicosmk_add_call_info_word (operands
[
0
]
);
return "lda $25,%0";
}
[
(set_attr "type" "iadd")
]
)
(define_insn "
*
movdi_er_low"
[
(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
...
...
@@ -4906,23 +5320,29 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
stt %R1,%0"
[
(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")
]
)
;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should
;; have been split up by the rules above but we shouldn't reject the
;; possibility of them getting through.
(define_insn "
*
movdi_nofix"
[
(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,
*f,*
f,Q")
(match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,
*fJ,Q,*
f"))]
"! TARGET_
EXPLICIT_RELOCS && ! TARGET_
FIX
[
(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,
r,
m,
*f,*
f,Q")
(match_operand:DI 1 "input_operand" "rJ,K,L,
U,
s,m,rJ,
*fJ,Q,*
f"))]
"! TARGET_FIX
&& (register_operand (operands
[
0
]
, DImode)
|| reg_or_0_operand (operands
[
1
]
, DImode))"
"@
mov
%r1,%0
bis $31,
%r1,%0
lda %0,%1($31)
ldah %0,%h1($31)
laum %0,%t1($31)
\;
sll %0,32,%0
\;
lalm %0,%t1(%0)
\;
lal %0,%t1(%0)
lda %0,%1
ldq%A1 %0,%1
stq%A0 %r1,%0
fmov
%R1,%0
cpys %R1,
%R1,%0
ldt %0,%1
stt %R1,%0"
[
(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")
]
)
[
(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,ild,ist,fcpys,fld,fst")
(set_attr "length" "
*,*
,
*,16,*
,
*,*
,
*,*
,
*
")])
(define_insn "
*
movdi_er_fix"
[
(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,
*f,*
f,Q,r,
*
f")
...
...
@@ -4953,13 +5373,13 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
&& (register_operand (operands
[
0
]
, DImode)
|| reg_or_0_operand (operands
[
1
]
, DImode))"
"@
mov
%r1,%0
bis $31,
%r1,%0
lda %0,%1($31)
ldah %0,%h1($31)
lda %0,%1
ldq%A1 %0,%1
stq%A0 %r1,%0
fmov
%R1,%0
cpys %R1,
%R1,%0
ldt %0,%1
stt %R1,%0
ftoit %1,%0
...
...
@@ -5041,12 +5461,29 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
"")
;; Similar for unaligned loads, where we use the sequence from the
;; Alpha Architecture manual.
;; Alpha Architecture manual. We have to distinguish between little-endian
;; and big-endian systems as the sequences are different.
;;
;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
;; operand 3 can overlap the input and output registers.
(define_expand "unaligned_loadqi"
[
(use (match_operand:QI 0 "register_operand" ""))
(use (match_operand:DI 1 "address_operand" ""))
(use (match_operand:DI 2 "register_operand" ""))
(use (match_operand:DI 3 "register_operand" ""))]
""
{
if (WORDS_BIG_ENDIAN)
emit_insn (gen_unaligned_loadqi_be (operands
[
0
]
, operands
[
1
]
,
operands
[
2
]
, operands
[
3
]
));
else
emit_insn (gen_unaligned_loadqi_le (operands
[
0
]
, operands
[
1
]
,
operands
[
2
]
, operands
[
3
]
));
DONE;
})
(define_expand "unaligned_loadqi_le"
[
(set (match_operand:DI 2 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
(const_int -8))))
...
...
@@ -5056,10 +5493,41 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(zero_extract:DI (match_dup 2)
(const_int 8)
(ashift:DI (match_dup 3) (const_int 3))))]
""
"! WORDS_BIG_ENDIAN"
"")
(define_expand "unaligned_loadqi_be"
[
(set (match_operand:DI 2 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
(const_int -8))))
(set (match_operand:DI 3 "register_operand" "")
(match_dup 1))
(set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
(zero_extract:DI (match_dup 2)
(const_int 8)
(minus:DI
(const_int 56)
(ashift:DI (match_dup 3) (const_int 3)))))]
"WORDS_BIG_ENDIAN"
"")
(define_expand "unaligned_loadhi"
[
(use (match_operand:QI 0 "register_operand" ""))
(use (match_operand:DI 1 "address_operand" ""))
(use (match_operand:DI 2 "register_operand" ""))
(use (match_operand:DI 3 "register_operand" ""))]
""
{
if (WORDS_BIG_ENDIAN)
emit_insn (gen_unaligned_loadhi_be (operands
[
0
]
, operands
[
1
]
,
operands
[
2
]
, operands
[
3
]
));
else
emit_insn (gen_unaligned_loadhi_le (operands
[
0
]
, operands
[
1
]
,
operands
[
2
]
, operands
[
3
]
));
DONE;
})
(define_expand "unaligned_loadhi_le"
[
(set (match_operand:DI 2 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
(const_int -8))))
...
...
@@ -5069,7 +5537,22 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(zero_extract:DI (match_dup 2)
(const_int 16)
(ashift:DI (match_dup 3) (const_int 3))))]
""
"! WORDS_BIG_ENDIAN"
"")
(define_expand "unaligned_loadhi_be"
[
(set (match_operand:DI 2 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
(const_int -8))))
(set (match_operand:DI 3 "register_operand" "")
(plus:DI (match_dup 1) (const_int 1)))
(set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
(zero_extract:DI (match_dup 2)
(const_int 16)
(minus:DI
(const_int 56)
(ashift:DI (match_dup 3) (const_int 3)))))]
"WORDS_BIG_ENDIAN"
"")
;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
...
...
@@ -5102,6 +5585,25 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
;; operand 2 can be that register.
(define_expand "unaligned_storeqi"
[
(use (match_operand:DI 0 "address_operand" ""))
(use (match_operand:QI 1 "register_operand" ""))
(use (match_operand:DI 2 "register_operand" ""))
(use (match_operand:DI 3 "register_operand" ""))
(use (match_operand:DI 4 "register_operand" ""))]
""
{
if (WORDS_BIG_ENDIAN)
emit_insn (gen_unaligned_storeqi_be (operands
[
0
]
, operands
[
1
]
,
operands
[
2
]
, operands
[
3
]
,
operands
[
4
]
));
else
emit_insn (gen_unaligned_storeqi_le (operands
[
0
]
, operands
[
1
]
,
operands
[
2
]
, operands
[
3
]
,
operands
[
4
]
));
DONE;
})
(define_expand "unaligned_storeqi_le"
[
(set (match_operand:DI 3 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
(const_int -8))))
...
...
@@ -5117,10 +5619,50 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
(match_dup 4))]
""
"! WORDS_BIG_ENDIAN"
"")
(define_expand "unaligned_storeqi_be"
[
(set (match_operand:DI 3 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
(const_int -8))))
(set (match_operand:DI 2 "register_operand" "")
(match_dup 0))
(set (match_dup 3)
(and:DI (not:DI (ashift:DI (const_int 255)
(minus:DI (const_int 56)
(ashift:DI (match_dup 2) (const_int 3)))))
(match_dup 3)))
(set (match_operand:DI 4 "register_operand" "")
(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
(minus:DI (const_int 56)
(ashift:DI (match_dup 2) (const_int 3)))))
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
(match_dup 4))]
"WORDS_BIG_ENDIAN"
"")
(define_expand "unaligned_storehi"
[
(use (match_operand:DI 0 "address_operand" ""))
(use (match_operand:HI 1 "register_operand" ""))
(use (match_operand:DI 2 "register_operand" ""))
(use (match_operand:DI 3 "register_operand" ""))
(use (match_operand:DI 4 "register_operand" ""))]
""
{
if (WORDS_BIG_ENDIAN)
emit_insn (gen_unaligned_storehi_be (operands
[
0
]
, operands
[
1
]
,
operands
[
2
]
, operands
[
3
]
,
operands
[
4
]
));
else
emit_insn (gen_unaligned_storehi_le (operands
[
0
]
, operands
[
1
]
,
operands
[
2
]
, operands
[
3
]
,
operands
[
4
]
));
DONE;
})
(define_expand "unaligned_storehi_le"
[
(set (match_operand:DI 3 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
(const_int -8))))
...
...
@@ -5136,7 +5678,29 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
(match_dup 4))]
""
"! WORDS_BIG_ENDIAN"
"")
(define_expand "unaligned_storehi_be"
[
(set (match_operand:DI 3 "register_operand" "")
(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
(const_int -8))))
(set (match_operand:DI 2 "register_operand" "")
(plus:DI (match_dup 0) (const_int 1)))
(set (match_dup 3)
(and:DI (not:DI (ashift:DI
(const_int 65535)
(minus:DI (const_int 56)
(ashift:DI (match_dup 2) (const_int 3)))))
(match_dup 3)))
(set (match_operand:DI 4 "register_operand" "")
(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
(minus:DI (const_int 56)
(ashift:DI (match_dup 2) (const_int 3)))))
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
(match_dup 4))]
"WORDS_BIG_ENDIAN"
"")
;; Here are the define_expand's for QI and HI moves that use the above
...
...
@@ -5356,6 +5920,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
{
rtx aligned_mem, bitnum;
get_aligned_mem (operands
[
1
]
, &aligned_mem,
&bitnum);
emit_insn (gen_aligned_loadqi (operands
[
0
]
, aligned_mem, bitnum,
operands
[
2
]
));
DONE;
...
...
@@ -5370,6 +5935,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
{
rtx aligned_mem, bitnum;
get_aligned_mem (operands
[
1
]
, &aligned_mem,
&bitnum);
emit_insn (gen_aligned_loadhi (operands
[
0
]
, aligned_mem, bitnum,
operands
[
2
]
));
DONE;
...
...
@@ -5414,6 +5980,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(match_operand:DI 3 "immediate_operand" "")))]
""
{
int ofs;
/
* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. *
/
if (INTVAL (operands
[
3
]
) % 8 != 0
|| (INTVAL (operands
[
2
]
) != 16
...
...
@@ -5426,9 +5994,21 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
if (GET_CODE (operands
[
1
]
) != MEM)
FAIL;
/
*
The bit number is relative to the mode of operand 1 which is
usually QImode (this might actually be a bug in expmed.c). Note
that the bit number is negative in big-endian mode in this case.
We have to convert that to the offset.
*
/
if (WORDS_BIG_ENDIAN)
ofs = GET_MODE_BITSIZE (GET_MODE (operands
[
1
]
))
-
INTVAL (operands
[
2
]
) - INTVAL (operands
[
3
]
);
else
ofs = INTVAL (operands
[
3
]
);
ofs = ofs / 8;
alpha_expand_unaligned_load (operands
[
0
]
, operands
[
1
]
,
INTVAL (operands
[
2
]
) / 8,
INTVAL (operands
[
3
]
) / 8
, 1);
ofs
, 1);
DONE;
})
...
...
@@ -5449,13 +6029,27 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
if (GET_CODE (operands
[
1
]
) == MEM)
{
int ofs;
/* Fail 8 bit fields, falling back on a simple byte load. */
if (INTVAL (operands[2]) == 8)
FAIL;
/* The bit number is relative to the mode of operand 1 which is
usually QImode (this might actually be a bug in expmed.c). Note
that the bit number is negative in big-endian mode in this case.
We have to convert that to the offset. */
if (WORDS_BIG_ENDIAN)
ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
- INTVAL (operands[2]) - INTVAL (operands[3]);
else
ofs = INTVAL (operands[3]);
ofs = ofs / 8;
alpha_expand_unaligned_load (operands[0], operands[1],
INTVAL (operands[2]) / 8,
INTVAL (operands[3]) / 8
, 0);
ofs
, 0);
DONE;
}
})
...
...
@@ -5467,6 +6061,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(match_operand:DI 3 "register_operand" ""))]
""
{
int ofs;
/
* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. *
/
if (INTVAL (operands
[
2
]
) % 8 != 0
|| (INTVAL (operands
[
1
]
) != 16
...
...
@@ -5479,9 +6075,20 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
if (GET_CODE (operands
[
0
]
) != MEM)
FAIL;
/
*
The bit number is relative to the mode of operand 1 which is
usually QImode (this might actually be a bug in expmed.c). Note
that the bit number is negative in big-endian mode in this case.
We have to convert that to the offset.
*
/
if (WORDS_BIG_ENDIAN)
ofs = GET_MODE_BITSIZE (GET_MODE (operands
[
0
]
))
-
INTVAL (operands
[
1
]
) - INTVAL (operands
[
2
]
);
else
ofs = INTVAL (operands
[
2
]
);
ofs = ofs / 8;
alpha_expand_unaligned_store (operands
[
0
]
, operands
[
3
]
,
INTVAL (operands
[
1
]
) / 8,
INTVAL (operands
[
2
]
) / 8);
INTVAL (operands
[
1
]
) / 8, ofs);
DONE;
})
...
...
@@ -5675,7 +6282,7 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
(match_operand:DI 1 "register_operand" "r"))
(clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
""
"
mov
%1,%0")
"
bis $31,
%1,%0")
(define_expand "epilogue"
[
(return)
]
...
...
@@ -5836,6 +6443,58 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
[
(set_attr "length" "16")
(set_attr "type" "multi")])
;; Load the CIW into r2 for calling __T3E_MISMATCH
(define_expand "umk_mismatch_args"
[
(set:DI (match_dup 1) (mem:DI (plus:DI (reg:DI 15) (const_int -16))))
(set:DI (match_dup 2) (mem:DI (plus:DI (match_dup 1) (const_int -32))))
(set:DI (reg:DI 1) (match_operand:DI 0 "const_int_operand" ""))
(set:DI (match_dup 3) (plus:DI (mult:DI (reg:DI 25)
(const_int 8))
(match_dup 2)))
(set:DI (reg:DI 2) (mem:DI (match_dup 3)))]
"TARGET_ABI_UNICOSMK"
{
operands
[
1
]
= gen_reg_rtx (DImode);
operands
[
2
]
= gen_reg_rtx (DImode);
operands
[
3
]
= gen_reg_rtx (DImode);
})
(define_insn "arg_home_umk"
[
(unspec [(const_int 0)
]
UNSPEC_ARG_HOME)
(use (reg:DI 1))
(use (reg:DI 2))
(use (reg:DI 16))
(use (reg:DI 17))
(use (reg:DI 18))
(use (reg:DI 19))
(use (reg:DI 20))
(use (reg:DI 21))
(use (reg:DI 48))
(use (reg:DI 49))
(use (reg:DI 50))
(use (reg:DI 51))
(use (reg:DI 52))
(use (reg:DI 53))
(clobber (mem:BLK (const_int 0)))
(parallel
[
(clobber (reg:DI 22))
(clobber (reg:DI 23))
(clobber (reg:DI 24))
(clobber (reg:DI 0))
(clobber (reg:DI 1))
(clobber (reg:DI 2))
(clobber (reg:DI 3))
(clobber (reg:DI 4))
(clobber (reg:DI 5))
(clobber (reg:DI 6))
(clobber (reg:DI 7))
(clobber (reg:DI 8))])]
"TARGET_ABI_UNICOSMK"
"laum $4,__T3E_MISMATCH($31)
\;
sll $4,32,$4
\;
lalm $4,__T3E_MISMATCH($4)
\;
lal $4,__T3E_MISMATCH($4)
\;
jsr $3,($4)"
[
(set_attr "length" "16")
(set_attr "type" "multi")])
;; Close the trap shadow of preceeding instructions. This is generated
;; by alpha_reorg.
...
...
@@ -5847,33 +6506,51 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
;; No-op instructions used by machine-dependant reorg to preserve
;; alignment for instruction issue.
;; The Unicos/Mk assembler does not support these opcodes.
(define_insn "nop"
[
(const_int 0)
]
""
"
nop
"
"
bis $31,$31,$31
"
[
(set_attr "type" "ilog")
]
)
(define_insn "fnop"
[
(const_int 1)
]
"TARGET_FP"
"
fnop
"
"
cpys $f31,$f31,$f31
"
[
(set_attr "type" "fcpys")
]
)
(define_insn "unop"
[
(const_int 2)
]
""
"unop")
"ldq_u $31,($31)")
;; On Unicos/Mk we use a macro for aligning code.
(define_insn "realign"
[
(unspec_volatile [(match_operand 0 "immediate_operand" "i")
]
UNSPECV_REALIGN)]
""
".align %0 #realign")
{
if (TARGET_ABI_UNICOSMK)
return "gcc@code@align %0";
else
return ".align %0 #realign";
})
;; The call patterns are at the end of the file because their
;; wildcard operand0 interferes with nice recognition.
(define_insn "
*
call_value_umk"
[
(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "call_operand" "r"))
(match_operand 2 "" "")))
(use (reg:DI 25))
(clobber (reg:DI 26))]
"TARGET_ABI_UNICOSMK"
"jsr $26,(%1)"
[
(set_attr "type" "jsr")
]
)
(define_insn "
*
call_value_osf_1_er"
[
(set (match_operand 0 "" "")
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,i"))
...
...
gcc/config/alpha/t-unicosmk
0 → 100644
View file @
30102605
# This file is empty for now.
gcc/config/alpha/unicosmk.h
0 → 100644
View file @
30102605
/* Definitions of target machine for GNU compiler, for DEC Alpha on Cray
T3E running Unicos/Mk.
Copyright (C) 2001
Free Software Foundation, Inc.
Contributed by Roman Lechtchinsky (rl@cs.tu-berlin.de)
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 2, 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, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef TARGET_ABI_UNICOSMK
#define TARGET_ABI_UNICOSMK 1
/* CAM requires a slash before floating-pointing instruction suffixes. */
#undef TARGET_AS_SLASH_BEFORE_SUFFIX
#define TARGET_AS_SLASH_BEFORE_SUFFIX 1
/* The following defines are necessary for the standard headers to work
correctly. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-D__unix=1 -D_UNICOS=205 -D_CRAY=1 -D_CRAYT3E=1 -D_CRAYMPP=1 -D_CRAYIEEE=1 -D_ADDR64=1 -D_LD64=1 -D__UNICOSMK__ -D__INT_MAX__=9223372036854775807 -D__SHRT_MAX__=2147483647"
/* Disable software floating point emulation because it requires a 16-bit
type which we do not have. */
#ifndef __GNUC__
#undef REAL_ARITHMETIC
#endif
#define SHORT_TYPE_SIZE 32
#undef INT_TYPE_SIZE
#define INT_TYPE_SIZE 64
/* This is consistent with the definition Cray CC uses. */
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 64
/*
#define SIZE_TYPE "unsigned int"
#define PTRDIFF_TYPE "int"
*/
/* Alphas are operated in big endian mode on the Cray T3E. */
#undef BITS_BIG_ENDIAN
#undef BYTES_BIG_ENDIAN
#undef WORDS_BIG_ENDIAN
#define BITS_BIG_ENDIAN 0
#define BYTES_BIG_ENDIAN 1
#define WORDS_BIG_ENDIAN 1
/* Every structure's size must be a multiple of this. */
#undef STRUCTURE_SIZE_BOUNDARY
#define STRUCTURE_SIZE_BOUNDARY 64
/* Allocation boundary (in *bits*) for the code of a function. Functions
should be cache-aligned on the T3E. */
#undef FUNCTION_BOUNDARY
#define FUNCTION_BOUNDARY 256
/* No data type wants to be aligned rounder than this. */
#undef BIGGEST_ALIGNMENT
#define BIGGEST_ALIGNMENT 256
/* Include the frame pointer in fixed_regs and call_used_regs as it can't be
used as a general-purpose register even in frameless functions.
??? The global_regs hack is needed for now because -O2 sometimes tries to
eliminate $15 increments/decrements in frameless functions. */
#undef CONDITIONAL_REGISTER_USAGE
#define CONDITIONAL_REGISTER_USAGE \
do { \
fixed_regs[15] = 1; \
call_used_regs[15] = 1; \
global_regs[15] = 1; \
} while(0)
/* The stack frame grows downward. */
#define FRAME_GROWS_DOWNWARD
/* Define the offset between two registers, one to be eliminated, and the
other its replacement, at the start of a routine. This is somewhat
complicated on the T3E which is why we use a function. */
extern
int
unicosmk_initial_elimination_offset
PARAMS
((
int
,
int
));
#undef INITIAL_ELIMINATION_OFFSET
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
do { \
(OFFSET) = unicosmk_initial_elimination_offset ((FROM), (TO)); \
} while (0)
/* Define this if stack space is still allocated for a parameter passed
in a register. On the T3E, stack space is preallocated for all outgoing
arguments, including those passed in registers. To avoid problems, we
assume that at least 48 bytes (i.e. enough space for all arguments passed
in registers) are allocated. */
#define REG_PARM_STACK_SPACE(DECL) 48
#define OUTGOING_REG_PARM_STACK_SPACE
/* If an argument can't be passed in registers even though not all argument
registers have been used yet, it is passed on the stack in the space
preallocated for these registers. */
#define STACK_PARMS_IN_REG_PARM_AREA
/* This evaluates to nonzero if we do not know how to pass TYPE solely in
registers. This is the case for all arguments that do not fit in two
registers. */
#define MUST_PASS_IN_STACK(MODE,TYPE) \
((TYPE) != 0 \
&& (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \
|| (TREE_ADDRESSABLE (TYPE) || ALPHA_ARG_SIZE (MODE, TYPE, 0) > 2)))
/* Define a data type for recording info about an argument list
during the scan of that argument list. This data type should
hold all necessary information about the function itself
and about the args processed so far, enough to enable macros
such as FUNCTION_ARG to determine where the next arg should go.
On Unicos/Mk, this is a structure that contains various information for
the static subroutine information block (SSIB) and the call information
word (CIW). */
typedef
struct
{
/* The overall number of arguments. */
int
num_args
;
/* The overall size of the arguments in words. */
int
num_arg_words
;
/* The number of words passed in registers. */
int
num_reg_words
;
/* If an argument must be passed in the stack, all subsequent arguments
must be passed there, too. This flag indicates whether this is the
case. */
int
force_stack
;
/* This array indicates whether a word is passed in an integer register or
a floating point one. */
/* For each of the 6 register arguments, the corresponding flag in this
array indicates whether the argument is passed in an integer or a
floating point register. */
int
reg_args_type
[
6
];
}
unicosmk_arg_info
;
#undef CUMULATIVE_ARGS
#define CUMULATIVE_ARGS unicosmk_arg_info
/* Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a
function whose data type is FNTYPE. For a library call, FNTYPE is 0. */
#undef INIT_CUMULATIVE_ARGS
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
do { (CUM).num_args = 0; \
(CUM).num_arg_words = 0; \
(CUM).num_reg_words = 0; \
(CUM).force_stack = 0; \
} while(0)
/* Update the data in CUM to advance over an argument of mode MODE and data
type TYPE. (TYPE is null for libcalls where that information may not be
available.)
On Unicos/Mk, at most 6 words can be passed in registers. Structures
which fit in two words are passed in registers, larger structures are
passed on stack. */
#undef FUNCTION_ARG_ADVANCE
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
do { \
int size; \
\
size = ALPHA_ARG_SIZE (MODE, TYPE, NAMED); \
\
if (size > 2 || MUST_PASS_IN_STACK (MODE, TYPE) \
|| (CUM).num_reg_words + size > 6) \
(CUM).force_stack = 1; \
\
if (! (CUM).force_stack) \
{ \
int i; \
int isfloat; \
isfloat = (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT \
|| GET_MODE_CLASS (MODE) == MODE_FLOAT); \
for (i = 0; i < size; i++) \
{ \
(CUM).reg_args_type[(CUM).num_reg_words] = isfloat; \
++(CUM).num_reg_words; \
} \
} \
(CUM).num_arg_words += size; \
++(CUM).num_args; \
} while(0)
/* We want the default definition for this.
??? In fact, we should delete the definition from alpha.h as it
corresponds to the default definition for little-endian machines. */
#undef FUNCTION_ARG_PADDING
/* An argument is passed either entirely in registers or entirely on stack. */
#undef FUNCTION_ARG_PARTIAL_NREGS
/* #define FUNCTION_ARG_PARTIAL_NREGS(CUM,MODE,TYPE,NAMED) 0 */
/* Perform any needed actions needed for a function that is receiving a
variable number of arguments.
On Unicos/Mk, the standard subroutine __T3E_MISMATCH stores all register
arguments on the stack. Unfortunately, it doesn't always store the first
one (i.e. the one that arrives in $16 or $f16). This is not a problem
with stdargs as we always have at least one named argument there. This is
not always the case when varargs.h is used, however. In such cases, we
have to store the first argument ourselves. We use the information from
the CIW to determine whether the first argument arrives in $16 or $f16. */
#undef SETUP_INCOMING_VARARGS
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
{ if ((CUM).num_reg_words < 6) \
{ \
if (! (NO_RTL)) \
{ \
int start; \
\
start = (CUM).num_reg_words; \
if (!current_function_varargs || start == 0) \
++start; \
\
emit_insn (gen_umk_mismatch_args (GEN_INT (start))); \
if (current_function_varargs && (CUM).num_reg_words == 0) \
{ \
rtx tmp; \
rtx int_label, end_label; \
\
tmp = gen_reg_rtx (DImode); \
emit_move_insn (tmp, \
gen_rtx_ZERO_EXTRACT (DImode, \
gen_rtx_REG (DImode, 2),\
(GEN_INT (1)), \
(GEN_INT (7)))); \
int_label = gen_label_rtx (); \
end_label = gen_label_rtx (); \
emit_insn (gen_cmpdi (tmp, GEN_INT (0))); \
emit_jump_insn (gen_beq (int_label)); \
emit_move_insn (gen_rtx_MEM (DFmode, virtual_incoming_args_rtx),\
gen_rtx_REG (DFmode, 48)); \
emit_jump (end_label); \
emit_label (int_label); \
emit_move_insn (gen_rtx_MEM (DImode, virtual_incoming_args_rtx),\
gen_rtx_REG (DImode, 16)); \
emit_label (end_label); \
} \
emit_insn (gen_arg_home_umk ()); \
} \
\
PRETEND_SIZE = 0; \
} \
}
/* This ensures that $15 increments/decrements in leaf functions won't get
eliminated. */
#undef EPILOGUE_USES
#define EPILOGUE_USES(REGNO) ((REGNO) == 26 || (REGNO) == 15)
/* Machine-specific function data. */
struct
machine_function
{
/* List of call information words for calls from this function. */
struct
rtx_def
*
first_ciw
;
struct
rtx_def
*
last_ciw
;
int
ciw_count
;
/* List of deferred case vectors. */
struct
rtx_def
*
addr_list
;
};
/* Would have worked, only the stack doesn't seem to be executable
#undef TRAMPOLINE_TEMPLATE
#define TRAMPOLINE_TEMPLATE(FILE) \
do { fprintf (FILE, "\tbr $1,0\n"); \
fprintf (FILE, "\tldq $0,12($1)\n"); \
fprintf (FILE, "\tldq $1,20($1)\n"); \
fprintf (FILE, "\tjmp $31,(r0)\n"); \
fprintf (FILE, "\tbis $31,$31,$31\n"); \
fprintf (FILE, "\tbis $31,$31,$31\n"); \
} while (0) */
/* We don't support nested functions (yet). */
#undef TRAMPOLINE_TEMPLATE
#define TRAMPOLINE_TEMPLATE(FILE) abort ()
/* Specify the machine mode that this machine uses for the index in the
tablejump instruction. On Unicos/Mk, we don't support relative case
vectors yet, thus the entries should be absolute addresses. */
#undef CASE_VECTOR_MODE
#define CASE_VECTOR_MODE DImode
#undef CASE_VECTOR_PC_RELATIVE
/* Define this as 1 if `char' should by default be signed; else as 0. */
/* #define DEFAULT_SIGNED_CHAR 1 */
/* The Cray assembler is really weird with respect to sections. It has only
named sections and you can't reopen a section once it has been closed.
This means that we have to generate unique names whenever we want to
reenter the text or the data section. The following is a rather bad hack
as TEXT_SECTION_ASM_OP and DATA_SECTION_ASM_OP are supposed to be
constants. */
#undef TEXT_SECTION_ASM_OP
#define TEXT_SECTION_ASM_OP unicosmk_text_section ()
#undef DATA_SECTION_ASM_OP
#define DATA_SECTION_ASM_OP unicosmk_data_section ()
/* There are ni read-only sections on Unicos/Mk. */
#undef READONLY_DATA_SECTION
#define READONLY_DATA_SECTION data_section
/* Define extra sections for common data and SSIBs (static subroutine
information blocks). The actual section header is output by the callers
of these functions. */
#undef EXTRA_SECTIONS
#undef EXTRA_SECTION_FUNCTIONS
#define EXTRA_SECTIONS in_common, in_ssib
#define EXTRA_SECTION_FUNCTIONS \
COMMON_SECTION \
SSIB_SECTION
#define COMMON_SECTION \
void \
common_section () \
{ \
in_section = in_common; \
}
#define SSIB_SECTION \
void \
ssib_section () \
{ \
in_section = in_ssib; \
}
/* A C expression which evaluates to true if declshould be placed into a
unique section for some target-specific reason. On Unicos/Mk, functions
and public variables are always placed in unique sections. */
/*
#define UNIQUE_SECTION_P(DECL) (TREE_PUBLIC (DECL) \
|| TREE_CODE (DECL) == FUNCTION_DECL)
*/
#define UNIQUE_SECTION(DECL, RELOC) unicosmk_unique_section (DECL, RELOC)
/* This outputs text to go at the start of an assembler file. */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE) unicosmk_asm_file_start (FILE)
/* This outputs text to go at the end of an assembler file. */
#undef ASM_FILE_END
#define ASM_FILE_END(FILE) unicosmk_asm_file_end (FILE)
/* We take care of that in ASM_FILE_START. */
#undef ASM_OUTPUT_SOURCE_FILENAME
/* There is no directive for declaring a label as global. Instead, an
additional colon must be appended when the label is defined. */
#undef ASM_GLOBALIZE_LABEL
#define ASM_GLOBALIZE_LABEL(FILE,NAME)
/* This is how to output a label for a jump table. Arguments are the same as
for ASM_OUTPUT_INTERNAL_LABEL, except the insn for the jump table is
passed. */
#undef ASM_OUTPUT_CASE_LABEL
#define ASM_OUTPUT_CASE_LABEL(FILE,PREFIX,NUM,TABLEINSN) \
ASM_OUTPUT_INTERNAL_LABEL (FILE, PREFIX, NUM)
/* This is how to output an assembler line defining a `double' constant. */
#undef ASM_OUTPUT_DOUBLE
#ifdef REAL_ARITHMETIC
#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
do { long t[2]; \
REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \
fprintf (FILE, "\t.quad ^X%lx%08lx\n", \
t[0] & 0xffffffff, t[1] & 0xffffffff); \
} while (0)
#else
#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
do { long t[2]; \
REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t); \
fprintf (FILE, "\t.quad ^X%x\n", t[0]); \
} while(0)
#endif
/* This is how to output an assembler line defining a `long double'
constant. `long double' and `double' are the same on the Cray T3E. */
#undef ASM_OUTPUT_LONG_DOUBLE
#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \
ASM_OUTPUT_DOUBLE (FILE,VALUE)
/* This is how to output an assembler line defining a `float' constant.
??? Somehow, REAL_VALUE_TO_TARGET_SINGLE gets confused and returns the
value in the upper bits of the int. */
#undef ASM_OUTPUT_FLOAT
#ifdef REAL_ARITHMETIC
#define ASM_OUTPUT_FLOAT(FILE,VALUE) \
do { long t; \
REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
fprintf (FILE, "\t.long ^X%x\n", t & 0xffffffff);\
} while (0)
#else
#define ASM_OUTPUT_FLOAT(FILE,VALUE) \
do { long t; \
REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t); \
fprintf (FILE, "\t.long ^X%x\n", (t >> 32) & 0xffffffff);\
} while(0)
#endif
/* CAM has some restrictions with respect to string literals. It won't
accept lines with more that 256 characters which means that we have
to split long strings. Moreover, it only accepts escape sequences of
the form \nnn in the range 0 to 127. We generate .byte directives for
escapes characters greater than 127. And finally, ` must be escaped. */
#undef ASM_OUTPUT_ASCII
#define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
do { \
FILE *_hide_asm_out_file = (MYFILE); \
const unsigned char *_hide_p = (const unsigned char *) (MYSTRING); \
int _hide_thissize = (MYLENGTH); \
int _size_so_far = 0; \
{ \
FILE *asm_out_file = _hide_asm_out_file; \
const unsigned char *p = _hide_p; \
int thissize = _hide_thissize; \
int in_ascii = 0; \
int i; \
\
for (i = 0; i < thissize; i++) \
{ \
register int c = p[i]; \
\
if (c > 127) \
{ \
if (in_ascii) \
{ \
fprintf (asm_out_file, "\"\n"); \
in_ascii = 0; \
} \
\
fprintf (asm_out_file, "\t.byte\t%d\n", c); \
} \
else \
{ \
if (! in_ascii) \
{ \
fprintf (asm_out_file, "\t.ascii\t\""); \
in_ascii = 1; \
_size_so_far = 0; \
} \
else if (_size_so_far >= 64) \
{ \
fprintf (asm_out_file, "\"\n\t.ascii\t\""); \
_size_so_far = 0; \
} \
\
if (c == '\"' || c == '\\' || c == '`') \
putc ('\\', asm_out_file); \
if (c >= ' ') \
putc (c, asm_out_file); \
else \
fprintf (asm_out_file, "\\%.3o", c); \
++ _size_so_far; \
} \
} \
if (in_ascii) \
fprintf (asm_out_file, "\"\n"); \
} \
} while(0)
/* This is how to output an element of a case-vector that is absolute. */
#undef ASM_OUTPUT_ADDR_VEC_ELT
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
fprintf (FILE, "\t.quad $L%d\n", (VALUE))
/* This is how to output an element of a case-vector that is relative.
(Unicos/Mk does not use such vectors yet). */
#undef ASM_OUTPUT_ADDR_DIFF_ELT
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) abort ()
/* We can't output case vectors in the same section as the function code
because CAM doesn't allow data definitions in code sections. Thus, we
simply record the case vectors and put them in a separate section after
the function. */
#define ASM_OUTPUT_ADDR_VEC(LAB,VEC) \
unicosmk_defer_case_vector ((LAB),(VEC))
#define ASM_OUTPUT_ADDR_DIFF_VEC(LAB,VEC) abort ()
/* This is how to output an assembler line that says to advance the location
counter to a multiple of 2**LOG bytes. Annoyingly, CAM always uses zeroes
to fill the unused space which does not work in code sections. We have to
be careful not to use the .align directive in code sections. */
#undef ASM_OUTPUT_ALIGN
#define ASM_OUTPUT_ALIGN(STREAM,LOG) unicosmk_output_align (STREAM, LOG)
/* This is how to advance the location counter by SIZE bytes. */
#undef ASM_OUTPUT_SKIP
#define ASM_OUTPUT_SKIP(STREAM,SIZE) \
fprintf ((STREAM), "\t.byte\t0:%d\n", (SIZE));
/* This says how to output an assembler line to define a global common
symbol. We need the alignment information because it has to be supplied
in the section header. */
#undef ASM_OUTPUT_COMMON
#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \
unicosmk_output_common ((FILE), (NAME), (SIZE), (ALIGN))
/* This says how to output an assembler line to define a local symbol. */
#undef ASM_OUTPUT_LOCAL
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
do { data_section (); \
fprintf (FILE, "\t.align\t%d\n", floor_log2 ((ALIGN) / BITS_PER_UNIT));\
ASM_OUTPUT_LABEL ((FILE), (NAME)); \
fprintf (FILE, "\t.byte 0:%d\n", SIZE); \
} while (0)
/* CAM does not allow us to declare a symbol as external first and then
define it in the same file later. Thus, we keep a list of all external
references, remove all symbols defined locally from it and output it at
the end of the asm file. */
#define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME) \
unicosmk_add_extern ((NAME))
#define ASM_OUTPUT_EXTERNAL_LIBCALL(STREAM,SYMREF) \
unicosmk_add_extern (XSTR ((SYMREF), 0))
/* This is how to declare an object. We don't have to output anything if
it is a global variable because those go into unique `common' sections
and the section name is globally visible. For local variables, we simply
output the label. In any case, we have to record that no extern
declaration should be generated for the symbol. */
#define ASM_DECLARE_OBJECT_NAME(STREAM,NAME,DECL) \
do { tree name_tree; \
name_tree = get_identifier ((NAME)); \
TREE_ASM_WRITTEN (name_tree) = 1; \
if (!TREE_PUBLIC (DECL)) \
{ \
assemble_name (STREAM, NAME); \
fputs (":\n", STREAM); \
} \
} while(0)
/*
#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \
unicosmk_output_section_name ((STREAM), (DECL), (NAME), (RELOC))
*/
/* Switch into a generic section. */
#define TARGET_ASM_NAMED_SECTION unicosmk_asm_named_section
#undef ASM_OUTPUT_MAX_SKIP_ALIGN
#define ASM_OUTPUT_MAX_SKIP_ALIGN(STREAM,POWER,MAXSKIP)
/* We have to define these because we do not use the floating-point
emulation. Unfortunately, atof does not accept hex literals. */
#ifndef REAL_ARITHMETIC
#define REAL_VALUE_ATOF(x,s) atof(x)
#define REAL_VALUE_HTOF(x,s) atof(x)
#endif
#undef NM_FLAGS
#undef OBJECT_FORMAT_COFF
/* We cannot generate debugging information on Unicos/Mk. */
#undef SDB_DEBUGGING_INFO
#undef MIPS_DEBUGGING_INFO
#undef DBX_DEBUGGING_INFO
#undef DWARF_DEBUGGING_INFO
#undef DWARF2_DEBUGGING_INFO
#undef DWARF2_UNWIND_INFO
#undef INCOMING_RETURN_ADDR_RTX
/* We use the functions provided by the system library for integer
division. */
#undef UDIVDI3_LIBCALL
#undef DIVDI3_LIBCALL
#define UDIVDI3_LIBCALL "$uldiv"
#define DIVDI3_LIBCALL "$sldiv"
#undef ASM_OUTPUT_SOURCE_LINE
/* We don't need a start file. */
#undef STARTFILE_SPEC
#define STARTFILE_SPEC ""
/* These are the libraries we have to link with.
??? The Craylibs directory should be autoconfed. */
#undef LIB_SPEC
#define LIB_SPEC "-L/opt/ctl/craylibs/craylibs -lu -lm -lc -lsma"
#undef BUILD_VA_LIST_TYPE
#undef EXPAND_BUILTIN_VA_START
#undef EXPAND_BUILTIN_VA_ARG
#define EH_FRAME_IN_DATA_SECTION 1
gcc/fixinc/fixincl.x
View file @
30102605
...
...
@@ -5,7 +5,7 @@
* files which are fixed to work correctly with ANSI C and placed in a
* directory that GNU C will search.
*
* This file contains 14
3
fixup descriptions.
* This file contains 14
4
fixup descriptions.
*
* See README for more information.
*
...
...
@@ -1954,7 +1954,7 @@ tSCC zHpux10_Cpp_Pow_InlineName[] =
* File name selection pattern
*/
tSCC zHpux10_Cpp_Pow_InlineList[] =
"|math.h|";
"|
fixinc-test-limits.h|
math.h|";
/*
* Machine/OS name selection pattern
*/
...
...
@@ -5107,6 +5107,43 @@ static const char* apzUndefine_NullPatch[] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Description of Unicosmk_Restrict fix
*/
tSCC zUnicosmk_RestrictName[] =
"unicosmk_restrict";
/*
* File name selection pattern
*/
tSCC zUnicosmk_RestrictList[] =
"|stdio.h|stdlib.h|wchar.h|";
/*
* Machine/OS name selection pattern
*/
tSCC* apzUnicosmk_RestrictMachs[] = {
"*-*-unicosmk*",
(const char*)NULL };
/*
* content selection pattern - do fix if pattern found
*/
tSCC zUnicosmk_RestrictSelect0[] =
"(\\*[ \t]*)restrict([ \t]+)";
#define UNICOSMK_RESTRICT_TEST_CT 1
static tTestDesc aUnicosmk_RestrictTests[] = {
{ TT_EGREP, zUnicosmk_RestrictSelect0, (regex_t*)NULL }, };
/*
* Fix Command Arguments for Unicosmk_Restrict
*/
static const char* apzUnicosmk_RestrictPatch[] = {
"format",
"%1__restrict__%2",
(char*)NULL };
/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Description of Uw7_Byteorder_Fix fix
*/
tSCC zUw7_Byteorder_FixName[] =
...
...
@@ -5577,9 +5614,9 @@ static const char* apzX11_SprintfPatch[] = {
*
* List of all fixes
*/
#define REGEX_COUNT 15
0
#define REGEX_COUNT 15
1
#define MACH_LIST_SIZE_LIMIT 279
#define FIX_COUNT 14
3
#define FIX_COUNT 14
4
/*
* Enumerate the fixes
...
...
@@ -5717,6 +5754,7 @@ typedef enum {
ULTRIX_STATIC_FIXIDX,
ULTRIX_STRINGS_FIXIDX,
UNDEFINE_NULL_FIXIDX,
UNICOSMK_RESTRICT_FIXIDX,
UW7_BYTEORDER_FIX_FIXIDX,
VA_I960_MACRO_FIXIDX,
VOID_NULL_FIXIDX,
...
...
@@ -6391,6 +6429,11 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
UNDEFINE_NULL_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aUndefine_NullTests, apzUndefine_NullPatch, 0 },
{ zUnicosmk_RestrictName, zUnicosmk_RestrictList,
apzUnicosmk_RestrictMachs,
UNICOSMK_RESTRICT_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aUnicosmk_RestrictTests, apzUnicosmk_RestrictPatch, 0 },
{ zUw7_Byteorder_FixName, zUw7_Byteorder_FixList,
apzUw7_Byteorder_FixMachs,
UW7_BYTEORDER_FIX_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
...
...
gcc/fixinc/inclhack.def
View file @
30102605
...
...
@@ -3102,6 +3102,23 @@ fix = {
test_text = "#define NULL 0UL\r\n#define NULL\t((void*)0)\n";
};
/*
* On Cray Unicos/Mk some standard headers use the C99 keyword "restrict"
* which must be replaced by __restrict__ for GCC.
*/
fix = {
hackname = unicosmk_restrict;
files = stdio.h;
files = stdlib.h;
files = wchar.h;
mach = "*-*-unicosmk*";
select = "(\\*[ \t]*)restrict([ \t]+)";
c_fix = format;
c_fix_arg = "%1__restrict__%2";
test_text = "void f (char * restrict x);";
};
/*
* If arpa/inet.h prototypes are incompatible with the ones we just
...
...
gcc/ginclude/stddef.h
View file @
30102605
...
...
@@ -165,6 +165,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
or if we want this type in particular. */
#if defined (_STDDEF_H) || defined (__need_size_t)
#ifndef __size_t__
/* BeOS */
#ifndef __SIZE_T__
/* Cray Unicos/Mk */
#ifndef _SIZE_T
/* in case <sys/types.h> has defined it. */
#ifndef _SYS_SIZE_T_H
#ifndef _T_SIZE_
...
...
@@ -179,6 +180,7 @@ typedef __PTRDIFF_TYPE__ ptrdiff_t;
#ifndef _SIZET_
#ifndef __size_t
#define __size_t__
/* BeOS */
#define __SIZE_T__
/* Cray Unicos/Mk */
#define _SIZE_T
#define _SYS_SIZE_T_H
#define _T_SIZE_
...
...
@@ -214,6 +216,7 @@ typedef long ssize_t;
#endif
/* _T_SIZE_ */
#endif
/* _SYS_SIZE_T_H */
#endif
/* _SIZE_T */
#endif
/* __SIZE_T__ */
#endif
/* __size_t__ */
#undef __need_size_t
#endif
/* _STDDEF_H or __need_size_t. */
...
...
@@ -228,6 +231,7 @@ typedef long ssize_t;
or if we want this type in particular. */
#if defined (_STDDEF_H) || defined (__need_wchar_t)
#ifndef __wchar_t__
/* BeOS */
#ifndef __WCHAR_T__
/* Cray Unicos/Mk */
#ifndef _WCHAR_T
#ifndef _T_WCHAR_
#ifndef _T_WCHAR
...
...
@@ -242,6 +246,7 @@ typedef long ssize_t;
#ifndef __INT_WCHAR_T_H
#ifndef _GCC_WCHAR_T
#define __wchar_t__
/* BeOS */
#define __WCHAR_T__
/* Cray Unicos/Mk */
#define _WCHAR_T
#define _T_WCHAR_
#define _T_WCHAR
...
...
@@ -300,6 +305,7 @@ typedef __WCHAR_TYPE__ wchar_t;
#endif
#endif
#endif
#endif
/* __WCHAR_T__ */
#endif
/* __wchar_t__ */
#undef __need_wchar_t
#endif
/* _STDDEF_H or __need_wchar_t. */
...
...
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