<s> static bool alpha_mode_dependent_address_p ( const_rtx addr , addr_space_t as ATTRIBUTE_UNUSED ) { return GET_CODE ( addr ) == AND ; } </s>

Return true if ADDR has an effect that depends on the machine mode it is used for . On the Alpha this is true only for the unaligned modes . We can simplify the test since we know that the address must be valid .


<s> static int alpha_multipass_dfa_lookahead ( void ) { return ( alpha_tune == PROCESSOR_EV6 ? 4 : 2 ) ; } </s>

How many alternative schedules to try . This should be as wide as the scheduling freedom in the DFA , but no wider . Making this value too large results extra work for the scheduler . For EV4 , loads can be issued to either IB0 or IB1 , thus we have 2 alternative schedules . For EV5 , we can choose between E0/E1 and FA/FM . For EV6 , an arithmetic insn can be issued to U0/U1/L0/L1 .


<s>
void
alpha_output_filename
(
FILE
*
stream
,
const
char
*
name
)
{
static
int
first_time
=
TRUE
;
if
(
first_time
)
{
first_time
=
FALSE
;
++
num_source_filenames
;
current_function_file
=
name
;
fprintf
(
stream
,
"\t.file\t%d "
,
num_source_filenames
)
;
output_quoted_string
(
stream
,
name
)
;
fprintf
(
stream
,
"\n"
)
;
}
else
if
(
name
!=
current_function_file
&&
strcmp
(
name
,
current_function_file
)
!=
0
)
{
++
num_source_filenames
;
current_function_file
=
name
;
fprintf
(
stream
,
"\t.file\t%d "
,
num_source_filenames
)
;
output_quoted_string
(
stream
,
name
)
;
fprintf
(
stream
,
"\n"
)
;
}
}
</s>

alpha
"\t.file\t%d "
"\n"
0
"\t.file\t%d "
"\n"


<s>
static
void
alpha_output_function_end_prologue
(
FILE
*
file
)
{
if
(
TARGET_ABI_OPEN_VMS
)
fputs
(
"\t.prologue\n"
,
file
)
;
else
if
(
!
flag_inhibit_size_directive
)
fprintf
(
file
,
"\t.prologue %d\n"
,
alpha_function_needs_gp
||
cfun
->
is_thunk
)
;
}
</s>

Emit the .prologue note at the scheduled end of the prologue .

alpha
"\t.prologue\n"
"\t.prologue %d\n"


<s> static void alpha_output_mi_thunk_osf ( FILE * file , tree thunk_fndecl ATTRIBUTE_UNUSED , HOST_WIDE_INT delta , HOST_WIDE_INT vcall_offset , tree function ) { const char * fnname = IDENTIFIER_POINTER ( DECL_ASSEMBLER_NAME ( thunk_fndecl ) ) ; HOST_WIDE_INT hi , lo ; rtx this_rtx , funexp ; rtx_insn * insn ; emit_insn ( gen_prologue_ldgp ( ) ) ; emit_note ( NOTE_INSN_PROLOGUE_END ) ; if ( aggregate_value_p ( TREE_TYPE ( TREE_TYPE ( function ) ) , function ) ) this_rtx = gen_rtx_REG ( Pmode , 17 ) ; else this_rtx = gen_rtx_REG ( Pmode , 16 ) ; lo = ( ( delta & 0xffff ) ^ 0x8000 ) - 0x8000 ; hi = ( ( ( delta - lo ) & 0xffffffff ) ^ 0x80000000 ) - 0x80000000 ; if ( hi + lo == delta ) { if ( hi ) emit_insn ( gen_adddi3 ( this_rtx , this_rtx , GEN_INT ( hi ) ) ) ; if ( lo ) emit_insn ( gen_adddi3 ( this_rtx , this_rtx , GEN_INT ( lo ) ) ) ; } else { rtx tmp = alpha_emit_set_long_const ( gen_rtx_REG ( Pmode , 0 ) , delta ) ; emit_insn ( gen_adddi3 ( this_rtx , this_rtx , tmp ) ) ; } if ( vcall_offset ) { rtx tmp , tmp2 ; tmp = gen_rtx_REG ( Pmode , 0 ) ; emit_move_insn ( tmp , gen_rtx_MEM ( Pmode , this_rtx ) ) ; lo = ( ( vcall_offset & 0xffff ) ^ 0x8000 ) - 0x8000 ; hi = ( ( ( vcall_offset - lo ) & 0xffffffff ) ^ 0x80000000 ) - 0x80000000 ; if ( hi + lo == vcall_offset ) { if ( hi ) emit_insn ( gen_adddi3 ( tmp , tmp , GEN_INT ( hi ) ) ) ; } else { tmp2 = alpha_emit_set_long_const ( gen_rtx_REG ( Pmode , 1 ) , vcall_offset ) ; emit_insn ( gen_adddi3 ( tmp , tmp , tmp2 ) ) ; lo = 0 ; } if ( lo ) tmp2 = gen_rtx_PLUS ( Pmode , tmp , GEN_INT ( lo ) ) ; else tmp2 = tmp ; emit_move_insn ( tmp , gen_rtx_MEM ( Pmode , tmp2 ) ) ; emit_insn ( gen_adddi3 ( this_rtx , this_rtx , tmp ) ) ; } if ( ! TREE_USED ( function ) ) { assemble_external ( function ) ; TREE_USED ( function ) = 1 ; } funexp = XEXP ( DECL_RTL ( function ) , 0 ) ; funexp = gen_rtx_MEM ( FUNCTION_MODE , funexp ) ; insn = emit_call_insn ( gen_sibcall ( funexp , const0_rtx ) ) ; SIBLING_CALL_P ( insn ) = 1 ; insn = get_insns ( ) ; shorten_branches ( insn ) ; assemble_start_function ( thunk_fndecl , fnname ) ; final_start_function ( insn , file , 1 ) ; final ( insn , file , 1 ) ; final_end_function ( ) ; assemble_end_function ( thunk_fndecl , fnname ) ; } </s>

Emit a tail call to FUNCTION after adjusting THIS by DELTA . In order to avoid the hordes of differences between generated code with and without TARGET_EXPLICIT_RELOCS , and to avoid duplicating lots of code loading up large constants , generate rtl and emit it instead of going straight to text . Not sure why this idea has n't been explored before ...


<s> static void alpha_override_options_after_change ( void ) { if ( optimize > 0 ) { if ( flag_align_loops && ! str_align_loops ) str_align_loops = "16" ; if ( flag_align_jumps && ! str_align_jumps ) str_align_jumps = "16" ; } if ( flag_align_functions && ! str_align_functions ) str_align_functions = "16" ; } </s>


<s> static void alpha_pad_function_end ( void ) { rtx_insn * insn , * next ; for ( insn = get_insns ( ) ; insn ; insn = NEXT_INSN ( insn ) ) { if ( ! CALL_P ( insn ) || ! ( SIBLING_CALL_P ( insn ) || find_reg_note ( insn , REG_NORETURN , NULL_RTX ) ) ) continue ; next = next_active_insn ( insn ) ; if ( next ) { rtx pat = PATTERN ( next ) ; if ( GET_CODE ( pat ) == SET && GET_CODE ( SET_SRC ( pat ) ) == UNSPEC_VOLATILE && XINT ( SET_SRC ( pat ) , 1 ) == UNSPECV_LDGP1 ) emit_insn_after ( gen_unop ( ) , insn ) ; } } } </s>

Insert an unop between sibcall or noreturn function call and GP load .


<s> static bool alpha_pass_by_reference ( cumulative_args_t , const function_arg_info & arg ) { if ( arg . mode == SFmode || arg . mode == SCmode ) return ! arg . named ; return arg . mode == TFmode || arg . mode == TCmode ; } </s>

Return true if TYPE should be passed by invisible reference .


<s> enum reg_class alpha_preferred_reload_class ( rtx x , enum reg_class rclass ) { if ( x == CONST0_RTX ( GET_MODE ( x ) ) ) return rclass ; if ( CONST_SCALAR_INT_P ( x ) || CONST_DOUBLE_P ( x ) || GET_CODE ( x ) == CONST_VECTOR ) { if ( rclass == FLOAT_REGS ) return NO_REGS ; if ( rclass == ALL_REGS ) return GENERAL_REGS ; return rclass ; } if ( CONSTANT_P ( x ) ) return ( rclass == ALL_REGS ? GENERAL_REGS : rclass ) ; return rclass ; } </s>

On the Alpha , all ( non-symbolic ) constants except zero go into a floating-point register via memory . Note that we can not return anything that is not a subset of CLASS , and that some symbolic constants can not be dropped to memory .


<s> static void alpha_pre_atomic_barrier ( enum memmodel model ) { if ( need_atomic_barrier_p ( model , true ) ) emit_insn ( gen_memory_barrier ( ) ) ; } </s>

Subroutines of the atomic operation splitters . Emit barriers as needed for the memory MODEL .


<s>
static
void
alpha_print_operand_address
(
FILE
*
file
,
machine_mode
,
rtx
addr
)
{
int
basereg
=
31
;
HOST_WIDE_INT
offset
=
0
;
if
(
GET_CODE
(
addr
)
==
AND
)
addr
=
XEXP
(
addr
,
0
)
;
if
(
GET_CODE
(
addr
)
==
PLUS
&&
CONST_INT_P
(
XEXP
(
addr
,
1
)
)
)
{
offset
=
INTVAL
(
XEXP
(
addr
,
1
)
)
;
addr
=
XEXP
(
addr
,
0
)
;
}
if
(
GET_CODE
(
addr
)
==
LO_SUM
)
{
const
char
*
reloc16
,
*
reloclo
;
rtx
op1
=
XEXP
(
addr
,
1
)
;
if
(
GET_CODE
(
op1
)
==
CONST
&&
GET_CODE
(
XEXP
(
op1
,
0
)
)
==
UNSPEC
)
{
op1
=
XEXP
(
op1
,
0
)
;
switch
(
XINT
(
op1
,
1
)
)
{
case
UNSPEC_DTPREL
:
reloc16
=
;
reloclo
=
(
alpha_tls_size
==
16
"dtprel"
:
"dtprello"
)
;
break
;
case
UNSPEC_TPREL
:
reloc16
=
;
reloclo
=
(
alpha_tls_size
==
16
"tprel"
:
"tprello"
)
;
break
;
default
:
output_operand_lossage
(
"unknown relocation unspec"
)
;
return
;
}
output_addr_const
(
file
,
XVECEXP
(
op1
,
0
,
0
)
)
;
}
else
{
reloc16
=
"gprel"
;
reloclo
=
"gprellow"
;
output_addr_const
(
file
,
op1
)
;
}
if
(
offset
)
fprintf
(
file
,
"+"
HOST_WIDE_INT_PRINT_DEC
,
offset
)
;
addr
=
XEXP
(
addr
,
0
)
;
switch
(
GET_CODE
(
addr
)
)
{
case
REG
:
basereg
=
REGNO
(
addr
)
;
break
;
case
SUBREG
:
basereg
=
subreg_regno
(
addr
)
;
break
;
default
:
gcc_unreachable
(
)
;
}
fprintf
(
file
,
"($%d)\t\t!%s"
,
basereg
,
(
basereg
==
29
reloc16
:
reloclo
)
)
;
return
;
}
switch
(
GET_CODE
(
addr
)
)
{
case
REG
:
basereg
=
REGNO
(
addr
)
;
break
;
case
SUBREG
:
basereg
=
subreg_regno
(
addr
)
;
break
;
case
CONST_INT
:
offset
=
INTVAL
(
addr
)
;
break
;
case
SYMBOL_REF
:
gcc_assert
(
TARGET_ABI_OPEN_VMS
||
this_is_asm_operands
)
;
fprintf
(
file
,
"%s"
,
XSTR
(
addr
,
0
)
)
;
return
;
case
CONST
:
gcc_assert
(
TARGET_ABI_OPEN_VMS
||
this_is_asm_operands
)
;
gcc_assert
(
GET_CODE
(
XEXP
(
addr
,
0
)
)
==
PLUS
&&
GET_CODE
(
XEXP
(
XEXP
(
addr
,
0
)
,
0
)
)
==
SYMBOL_REF
)
;
fprintf
(
file
,
"%s+"
HOST_WIDE_INT_PRINT_DEC
,
XSTR
(
XEXP
(
XEXP
(
addr
,
0
)
,
0
)
,
0
)
,
INTVAL
(
XEXP
(
XEXP
(
addr
,
0
)
,
1
)
)
)
;
return
;
default
:
output_operand_lossage
(
"invalid operand address"
)
;
return
;
}
fprintf
(
file
,
HOST_WIDE_INT_PRINT_DEC
"($%d)"
,
offset
,
basereg
)
;
}
</s>


<s> static bool alpha_print_operand_punct_valid_p ( unsigned char code ) { return ( code == '/' || code == ',' || code == '-' || code == '~' || code == '#' || code == '*' || code == '&' ) ; } </s>


<s> static int alpha_register_move_cost ( machine_mode , reg_class_t from , reg_class_t to ) { if ( ( from == FLOAT_REGS ) == ( to == FLOAT_REGS ) ) return 2 ; if ( TARGET_FIX ) return ( from == FLOAT_REGS ) ? 6 : 8 ; return 4 + 2 * alpha_memory_latency ; } </s>

Return the cost of moving between registers of various classes . Moving between FLOAT_REGS and anything else except float regs is expensive . In fact , we make it quite expensive because we really do n't want to do these moves unless it is clearly worth it . Optimizations may reduce the impact of not being able to allocate a pseudo to a hard register .


<s> static void alpha_reorg ( void ) { if ( current_function_has_exception_handlers ( ) ) alpha_pad_function_end ( ) ; rtx_insn * insn = prev_active_insn ( get_last_insn ( ) ) ; if ( insn && NONJUMP_INSN_P ( insn ) ) { rtx pat = PATTERN ( insn ) ; if ( GET_CODE ( pat ) == PARALLEL ) { rtx vec = XVECEXP ( pat , 0 , 0 ) ; if ( GET_CODE ( vec ) == TRAP_IF && XEXP ( vec , 0 ) == const1_rtx ) emit_insn_after ( gen_unop ( ) , insn ) ; } } } </s>


<s> rtx alpha_return_addr ( int count , rtx frame ATTRIBUTE_UNUSED ) { if ( count != 0 ) return const0_rtx ; return get_hard_reg_initial_val ( Pmode , REG_RA ) ; } </s>

Start the ball rolling with RETURN_ADDR_RTX .


<s> static bool alpha_return_in_memory ( const_tree type , const_tree fndecl ATTRIBUTE_UNUSED ) { machine_mode mode = VOIDmode ; int size ; if ( type ) { mode = TYPE_MODE ( type ) ; if ( TARGET_ABI_OPEN_VMS && TREE_CODE ( type ) != ARRAY_TYPE && ( unsigned HOST_WIDE_INT ) int_size_in_bytes ( type ) <= 8 ) return false ; if ( AGGREGATE_TYPE_P ( type ) ) return true ; } size = GET_MODE_SIZE ( mode ) ; switch ( GET_MODE_CLASS ( mode ) ) { case MODE_VECTOR_FLOAT : return true ; case MODE_COMPLEX_FLOAT : size = GET_MODE_UNIT_SIZE ( mode ) ; break ; case MODE_INT : case MODE_FLOAT : case MODE_COMPLEX_INT : case MODE_VECTOR_INT : break ; default : return true ; } return size > UNITS_PER_WORD ; } </s>

Return true if TYPE must be returned in memory , instead of in registers .


<s> static bool alpha_scalar_mode_supported_p ( scalar_mode mode ) { switch ( mode ) { case E_QImode : case E_HImode : case E_SImode : case E_DImode : case E_TImode : return true ; case E_SFmode : case E_DFmode : return true ; case E_TFmode : return TARGET_HAS_XFLOATING_LIBS ; default : return false ; } } </s>

The scalar modes supported differs from the default check-what-c-supports version in that sometimes TFmode is available even when long double indicates only DFmode . On unicosmk , we have the situation that HImode does n't map to any C type , but of course we still support that .


Implement TARGET_SECONDARY_MEMORY_NEEDED . If we are copying between general and FP registers , we need a memory location unless the FIX extension is available .


<s> static machine_mode alpha_secondary_memory_needed_mode ( machine_mode mode ) { if ( GET_MODE_CLASS ( mode ) == MODE_FLOAT ) return mode ; if ( GET_MODE_SIZE ( mode ) >= 4 ) return mode ; return mode_for_size ( BITS_PER_WORD , GET_MODE_CLASS ( mode ) , 0 ) . require ( ) ; } </s>

Implement TARGET_SECONDARY_MEMORY_NEEDED_MODE . If MODE is floating-point , use it . Otherwise , widen to a word like the default . This is needed because we always store integers in FP registers in quadword format . This whole area is very tricky !


<s> static reg_class_t alpha_secondary_reload ( bool in_p , rtx x , reg_class_t rclass_i , machine_mode mode , secondary_reload_info * sri ) { enum reg_class rclass = ( enum reg_class ) rclass_i ; if ( ! TARGET_BWX && ( mode == QImode || mode == HImode || mode == CQImode ) ) { if ( any_memory_operand ( x , mode ) ) { if ( in_p ) { if ( ! aligned_memory_operand ( x , mode ) ) sri -> icode = direct_optab_handler ( reload_in_optab , mode ) ; } else sri -> icode = direct_optab_handler ( reload_out_optab , mode ) ; return NO_REGS ; } } if ( rclass == FLOAT_REGS ) { if ( MEM_P ( x ) && GET_CODE ( XEXP ( x , 0 ) ) == AND ) return GENERAL_REGS ; if ( in_p && INTEGRAL_MODE_P ( mode ) && ! MEM_P ( x ) && ! REG_P ( x ) && ! CONST_INT_P ( x ) ) return GENERAL_REGS ; } return NO_REGS ; } </s>

Inform reload about cases where moving X with a mode MODE to a register in RCLASS requires an extra scratch or immediate register . Return the class needed for the immediate register .


<s> static void alpha_setup_incoming_varargs ( cumulative_args_t pcum , const function_arg_info & arg , int * pretend_size , int no_rtl ) { CUMULATIVE_ARGS cum = * get_cumulative_args ( pcum ) ; targetm . calls . function_arg_advance ( pack_cumulative_args ( & cum ) , arg ) ; if ( cum . num_args < 6 ) { if ( ! no_rtl ) { emit_move_insn ( gen_rtx_REG ( DImode , 1 ) , virtual_incoming_args_rtx ) ; emit_insn ( gen_arg_home ( ) ) ; } * pretend_size = 7 * UNITS_PER_WORD ; } if ( cum >= 6 ) return ; if ( ! no_rtl ) { int count ; alias_set_type set = get_varargs_alias_set ( ) ; rtx tmp ; count = cfun -> va_list_gpr_size / UNITS_PER_WORD ; if ( count > 6 - cum ) count = 6 - cum ; gcc_assert ( ( VA_LIST_MAX_FPR_SIZE & 3 ) == 3 ) ; if ( cfun -> va_list_fpr_size & 1 ) { tmp = gen_rtx_MEM ( BLKmode , plus_constant ( Pmode , virtual_incoming_args_rtx , ( cum + 6 ) * UNITS_PER_WORD ) ) ; MEM_NOTRAP_P ( tmp ) = 1 ; set_mem_alias_set ( tmp , set ) ; move_block_from_reg ( 16 + cum , tmp , count ) ; } if ( cfun -> va_list_fpr_size & 2 ) { tmp = gen_rtx_MEM ( BLKmode , plus_constant ( Pmode , virtual_incoming_args_rtx , cum * UNITS_PER_WORD ) ) ; MEM_NOTRAP_P ( tmp ) = 1 ; set_mem_alias_set ( tmp , set ) ; move_block_from_reg ( 16 + cum + TARGET_FPREGS * 32 , tmp , count ) ; } } * pretend_size = 12 * UNITS_PER_WORD ; } </s>

Perform any needed actions needed for a function that is receiving a variable number of arguments .


<s> void alpha_set_memflags ( rtx seq , rtx ref ) { rtx_insn * insn ; if ( ! MEM_P ( ref ) ) return ; if ( ! MEM_VOLATILE_P ( ref ) && ! MEM_NOTRAP_P ( ref ) && ! MEM_READONLY_P ( ref ) ) return ; subrtx_var_iterator :: array_type array ; for ( insn = as_a < rtx_insn * > ( seq ) ; insn ; insn = NEXT_INSN ( insn ) ) if ( INSN_P ( insn ) ) FOR_EACH_SUBRTX_VAR ( iter , array , PATTERN ( insn ) , NONCONST ) { rtx x = * iter ; if ( MEM_P ( x ) ) { MEM_VOLATILE_P ( x ) = MEM_VOLATILE_P ( ref ) ; MEM_NOTRAP_P ( x ) = MEM_NOTRAP_P ( ref ) ; MEM_READONLY_P ( x ) = MEM_READONLY_P ( ref ) ; iter . skip_subrtxes ( ) ; } } else gcc_unreachable ( ) ; } </s>

Given INSN , which is an INSN list or the PATTERN of a single insn generated to perform a memory operation , look for any MEMs in either a SET_DEST or a SET_SRC and copy the in-struct , unchanging , and volatile flags from REF into each of the MEMs found . If REF is not a MEM , do n't do anything .


<s> void alpha_split_atomic_exchange ( rtx operands [ ] ) { rtx retval , mem , val , scratch ; enum memmodel model ; machine_mode mode ; rtx label , x , cond ; retval = operands [ 0 ] ; mem = operands [ 1 ] ; val = operands [ 2 ] ; model = ( enum memmodel ) INTVAL ( operands [ 3 ] ) ; scratch = operands [ 4 ] ; mode = GET_MODE ( mem ) ; cond = gen_lowpart ( DImode , scratch ) ; alpha_pre_atomic_barrier ( model ) ; label = gen_rtx_LABEL_REF ( DImode , gen_label_rtx ( ) ) ; emit_label ( XEXP ( label , 0 ) ) ; emit_insn ( gen_load_locked ( mode , retval , mem ) ) ; emit_move_insn ( scratch , val ) ; emit_insn ( gen_store_conditional ( mode , cond , mem , scratch ) ) ; x = gen_rtx_EQ ( DImode , cond , const0_rtx ) ; emit_unlikely_jump ( x , label ) ; alpha_post_atomic_barrier ( model ) ; } </s>


<s> void alpha_split_atomic_op ( enum rtx_code code , rtx mem , rtx val , rtx before , rtx after , rtx scratch , enum memmodel model ) { machine_mode mode = GET_MODE ( mem ) ; rtx label , x , cond = gen_rtx_REG ( DImode , REGNO ( scratch ) ) ; alpha_pre_atomic_barrier ( model ) ; label = gen_label_rtx ( ) ; emit_label ( label ) ; label = gen_rtx_LABEL_REF ( DImode , label ) ; if ( before == NULL ) before = scratch ; emit_insn ( gen_load_locked ( mode , before , mem ) ) ; if ( code == NOT ) { x = gen_rtx_AND ( mode , before , val ) ; emit_insn ( gen_rtx_SET ( val , x ) ) ; x = gen_rtx_NOT ( mode , val ) ; } else x = gen_rtx_fmt_ee ( code , mode , before , val ) ; if ( after ) emit_insn ( gen_rtx_SET ( after , copy_rtx ( x ) ) ) ; emit_insn ( gen_rtx_SET ( scratch , x ) ) ; emit_insn ( gen_store_conditional ( mode , cond , mem , scratch ) ) ; x = gen_rtx_EQ ( DImode , cond , const0_rtx ) ; emit_unlikely_jump ( x , label ) ; alpha_post_atomic_barrier ( model ) ; } </s>

Expand an an atomic fetch-and-operate pattern . CODE is the binary operation to perform . MEM is the memory on which to operate . VAL is the second operand of the binary operator . BEFORE and AFTER are optional locations to return the value of MEM either before of after the operation . SCRATCH is a scratch register .


<s> void alpha_split_compare_and_swap ( rtx operands [ ] ) { rtx cond , retval , mem , oldval , newval ; bool is_weak ; enum memmodel mod_s , mod_f ; machine_mode mode ; rtx label1 , label2 , x ; cond = operands [ 0 ] ; retval = operands [ 1 ] ; mem = operands [ 2 ] ; oldval = operands [ 3 ] ; newval = operands [ 4 ] ; is_weak = ( operands [ 5 ] != const0_rtx ) ; mod_s = memmodel_from_int ( INTVAL ( operands [ 6 ] ) ) ; mod_f = memmodel_from_int ( INTVAL ( operands [ 7 ] ) ) ; mode = GET_MODE ( mem ) ; alpha_pre_atomic_barrier ( mod_s ) ; label1 = NULL_RTX ; if ( ! is_weak ) { label1 = gen_rtx_LABEL_REF ( DImode , gen_label_rtx ( ) ) ; emit_label ( XEXP ( label1 , 0 ) ) ; } label2 = gen_rtx_LABEL_REF ( DImode , gen_label_rtx ( ) ) ; emit_insn ( gen_load_locked ( mode , retval , mem ) ) ; x = gen_lowpart ( DImode , retval ) ; if ( oldval == const0_rtx ) { emit_move_insn ( cond , const0_rtx ) ; x = gen_rtx_NE ( DImode , x , const0_rtx ) ; } else { x = gen_rtx_EQ ( DImode , x , oldval ) ; emit_insn ( gen_rtx_SET ( cond , x ) ) ; x = gen_rtx_EQ ( DImode , cond , const0_rtx ) ; } emit_unlikely_jump ( x , label2 ) ; emit_move_insn ( cond , newval ) ; emit_insn ( gen_store_conditional ( mode , cond , mem , gen_lowpart ( mode , cond ) ) ) ; if ( ! is_weak ) { x = gen_rtx_EQ ( DImode , cond , const0_rtx ) ; emit_unlikely_jump ( x , label1 ) ; } if ( ! is_mm_relaxed ( mod_f ) ) emit_label ( XEXP ( label2 , 0 ) ) ; alpha_post_atomic_barrier ( mod_s ) ; if ( is_mm_relaxed ( mod_f ) ) emit_label ( XEXP ( label2 , 0 ) ) ; } </s>


<s> static bool alpha_split_complex_arg ( const_tree type ) { return TYPE_MODE ( type ) != TCmode ; } </s>

TCmode complex values are passed by invisible reference . We should not split these values .


<s> int alpha_split_conditional_move ( enum rtx_code code , rtx dest , rtx cond , rtx t_rtx , rtx f_rtx ) { HOST_WIDE_INT t , f , diff ; machine_mode mode ; rtx target , subtarget , tmp ; mode = GET_MODE ( dest ) ; t = INTVAL ( t_rtx ) ; f = INTVAL ( f_rtx ) ; diff = t - f ; if ( ( ( code == NE || code == EQ ) && diff < 0 ) || ( code == GE || code == GT ) ) { code = reverse_condition ( code ) ; std :: swap ( t , f ) ; diff = - diff ; } subtarget = target = dest ; if ( mode != DImode ) { target = gen_lowpart ( DImode , dest ) ; if ( can_create_pseudo_p ( ) ) subtarget = gen_reg_rtx ( DImode ) ; else subtarget = target ; } if ( f == 0 && exact_log2 ( diff ) > 0 && ( diff <= 8 || alpha_tune == PROCESSOR_EV6 ) ) { tmp = gen_rtx_fmt_ee ( code , DImode , cond , const0_rtx ) ; emit_insn ( gen_rtx_SET ( copy_rtx ( subtarget ) , tmp ) ) ; tmp = gen_rtx_ASHIFT ( DImode , copy_rtx ( subtarget ) , GEN_INT ( exact_log2 ( t ) ) ) ; emit_insn ( gen_rtx_SET ( target , tmp ) ) ; } else if ( f == 0 && t == - 1 ) { tmp = gen_rtx_fmt_ee ( code , DImode , cond , const0_rtx ) ; emit_insn ( gen_rtx_SET ( copy_rtx ( subtarget ) , tmp ) ) ; emit_insn ( gen_negdi2 ( target , copy_rtx ( subtarget ) ) ) ; } else if ( diff == 1 || diff == 4 || diff == 8 ) { rtx add_op ; tmp = gen_rtx_fmt_ee ( code , DImode , cond , const0_rtx ) ; emit_insn ( gen_rtx_SET ( copy_rtx ( subtarget ) , tmp ) ) ; if ( diff == 1 ) emit_insn ( gen_adddi3 ( target , copy_rtx ( subtarget ) , GEN_INT ( f ) ) ) ; else { add_op = GEN_INT ( f ) ; if ( sext_add_operand ( add_op , mode ) ) { tmp = gen_rtx_ASHIFT ( DImode , copy_rtx ( subtarget ) , GEN_INT ( exact_log2 ( diff ) ) ) ; tmp = gen_rtx_PLUS ( DImode , tmp , add_op ) ; emit_insn ( gen_rtx_SET ( target , tmp ) ) ; } else return 0 ; } } else return 0 ; return 1 ; } </s>

Simplify a conditional move of two constants into a setcc with arithmetic . This is done with a splitter since combine would just undo the work if done during code generation . It also catches cases we would n't have before cse .


<s> bool alpha_split_const_mov ( machine_mode mode , rtx * operands ) { HOST_WIDE_INT i0 ; rtx temp = NULL_RTX ; i0 = alpha_extract_integer ( operands [ 1 ] ) ; temp = alpha_emit_set_const ( operands [ 0 ] , mode , i0 , 3 , false ) ; if ( ! temp && TARGET_BUILD_CONSTANTS ) temp = alpha_emit_set_long_const ( operands [ 0 ] , i0 ) ; if ( temp ) { if ( ! rtx_equal_p ( operands [ 0 ] , temp ) ) emit_move_insn ( operands [ 0 ] , temp ) ; return true ; } return false ; } </s>

Operand 1 is known to be a constant , and should require more than one instruction to load . Emit that multi-part load .


<s> void alpha_split_tfmode_frobsign ( rtx operands [ 3 ] , rtx ( * operation ) ( rtx , rtx , rtx ) ) { rtx high_bit = operands [ 2 ] ; rtx scratch ; int move ; alpha_split_tmode_pair ( operands , TFmode , false ) ; move = 1 ; if ( rtx_equal_p ( operands [ 0 ] , operands [ 2 ] ) ) move = 0 ; else if ( rtx_equal_p ( operands [ 1 ] , operands [ 2 ] ) ) { if ( rtx_equal_p ( operands [ 0 ] , high_bit ) ) move = 2 ; else move = - 1 ; } if ( move < 0 ) emit_move_insn ( operands [ 0 ] , operands [ 2 ] ) ; scratch = operands [ move < 2 ? 1 : 3 ] ; emit_insn ( ( * operation ) ( scratch , high_bit , operands [ 3 ] ) ) ; if ( move > 0 ) { emit_move_insn ( operands [ 0 ] , operands [ 2 ] ) ; if ( move > 1 ) emit_move_insn ( operands [ 1 ] , scratch ) ; } } </s>

Implement negtf2 or abstf2 . Op0 is destination , op1 is source , op2 is a register containing the sign bit , operation is the logical operation to be performed .


<s> void alpha_split_tmode_pair ( rtx operands [ 4 ] , machine_mode mode , bool fixup_overlap ) { switch ( GET_CODE ( operands [ 1 ] ) ) { case REG : operands [ 3 ] = gen_rtx_REG ( DImode , REGNO ( operands [ 1 ] ) + 1 ) ; operands [ 2 ] = gen_rtx_REG ( DImode , REGNO ( operands [ 1 ] ) ) ; break ; case MEM : operands [ 3 ] = adjust_address ( operands [ 1 ] , DImode , 8 ) ; operands [ 2 ] = adjust_address ( operands [ 1 ] , DImode , 0 ) ; break ; CASE_CONST_SCALAR_INT : case CONST_DOUBLE : gcc_assert ( operands [ 1 ] == CONST0_RTX ( mode ) ) ; operands [ 2 ] = operands [ 3 ] = const0_rtx ; break ; default : gcc_unreachable ( ) ; } switch ( GET_CODE ( operands [ 0 ] ) ) { case REG : operands [ 1 ] = gen_rtx_REG ( DImode , REGNO ( operands [ 0 ] ) + 1 ) ; operands [ 0 ] = gen_rtx_REG ( DImode , REGNO ( operands [ 0 ] ) ) ; break ; case MEM : operands [ 1 ] = adjust_address ( operands [ 0 ] , DImode , 8 ) ; operands [ 0 ] = adjust_address ( operands [ 0 ] , DImode , 0 ) ; break ; default : gcc_unreachable ( ) ; } if ( fixup_overlap && reg_overlap_mentioned_p ( operands [ 0 ] , operands [ 3 ] ) ) { std :: swap ( operands [ 0 ] , operands [ 1 ] ) ; std :: swap ( operands [ 2 ] , operands [ 3 ] ) ; } } </s>

Split a TImode or TFmode move from OP [ 1 ] to OP [ 0 ] into a pair of DImode moves from OP [ 2,3 ] to OP [ 0,1 ] . If FIXUP_OVERLAP is true , guarantee that the sequence set ( OP [ 0 ] OP [ 2 ] ) set ( OP [ 1 ] OP [ 3 ] ) is valid . Naturally , output operand ordering is little-endian . This is used by * movtf_internal and * movti_internal .


<s> static void alpha_trampoline_init ( rtx m_tramp , tree fndecl , rtx chain_value ) { rtx fnaddr , mem , word1 , word2 ; fnaddr = XEXP ( DECL_RTL ( fndecl ) , 0 ) ; fnaddr = convert_memory_address ( Pmode , fnaddr ) ; chain_value = convert_memory_address ( Pmode , chain_value ) ; if ( TARGET_ABI_OPEN_VMS ) { const char * fnname ; char * trname ; fnname = XSTR ( fnaddr , 0 ) ; trname = ( char * ) alloca ( strlen ( fnname ) + 5 ) ; strcpy ( trname , fnname ) ; strcat ( trname , "..tr" ) ; fnname = ggc_alloc_string ( trname , strlen ( trname ) + 1 ) ; word2 = gen_rtx_SYMBOL_REF ( Pmode , fnname ) ; word1 = force_reg ( DImode , gen_const_mem ( DImode , fnaddr ) ) ; word1 = expand_and ( DImode , word1 , GEN_INT ( HOST_WIDE_INT_C ( 0xffff0fff0000fff0 ) ) , NULL ) ; } else { word1 = GEN_INT ( HOST_WIDE_INT_C ( 0xa77b0010a43b0018 ) ) ; word2 = GEN_INT ( HOST_WIDE_INT_C ( 0x47ff041f6bfb0000 ) ) ; } mem = adjust_address ( m_tramp , DImode , 0 ) ; emit_move_insn ( mem , word1 ) ; mem = adjust_address ( m_tramp , DImode , 8 ) ; emit_move_insn ( mem , word2 ) ; mem = adjust_address ( m_tramp , Pmode , 16 ) ; emit_move_insn ( mem , fnaddr ) ; mem = adjust_address ( m_tramp , Pmode , 24 ) ; emit_move_insn ( mem , chain_value ) ; if ( TARGET_ABI_OSF ) { emit_insn ( gen_imb ( ) ) ; emit_library_call ( init_one_libfunc ( "__enable_execute_stack" ) , LCT_NORMAL , VOIDmode , XEXP ( m_tramp , 0 ) , Pmode ) ; } } </s>

Emit RTL insns to initialize the variable parts of a trampoline at M_TRAMP . FNDECL is target function 's decl . CHAIN_VALUE is an rtx for the static chain value for the function .


<s> rtx alpha_use_linkage ( rtx func ATTRIBUTE_UNUSED , bool lflag ATTRIBUTE_UNUSED , bool rflag ATTRIBUTE_UNUSED ) { return NULL_RTX ; } </s>

Return a SYMBOL_REF representing the reference to the .linkage entry of function FUNC built for calls made from CFUNDECL . LFLAG is 1 if this is the reference to the linkage pointer value , 0 if this is the reference to the function entry value . RFLAG is 1 if this a reduced reference ( code address only ) , 0 if this is a full reference .


<s> static bool alpha_vector_mode_supported_p ( machine_mode mode ) { return mode == V8QImode || mode == V4HImode || mode == V2SImode ; } </s>

Alpha implements a couple of integer vector mode operations when TARGET_MAX is enabled . We do not check TARGET_MAX here , however , which allows the vectorizer to operate on e.g . move instructions , or when expand_vector_operations can do something useful .


<s> static bool alpha_vms_can_eliminate ( const int from ATTRIBUTE_UNUSED , const int to ) { switch ( alpha_procedure_type ) { case PT_NULL : return to == STACK_POINTER_REGNUM ; case PT_REGISTER : case PT_STACK : return ( to != STACK_POINTER_REGNUM || vms_unwind_regno != HARD_FRAME_POINTER_REGNUM ) ; } gcc_unreachable ( ) ; } </s>

Worker function for TARGET_CAN_ELIMINATE .


<s> HOST_WIDE_INT alpha_vms_initial_elimination_offset ( unsigned int from , unsigned int to ) { HOST_WIDE_INT sa_size = cfun -> machine -> sa_size ; if ( alpha_procedure_type == PT_NULL ) return 0 ; { HOST_WIDE_INT offset ; HOST_WIDE_INT pv_save_size = alpha_procedure_type == PT_STACK ? 8 : 0 ; switch ( from ) { case FRAME_POINTER_REGNUM : offset = ALPHA_ROUND ( sa_size + pv_save_size ) ; break ; case ARG_POINTER_REGNUM : offset = ( ALPHA_ROUND ( sa_size + pv_save_size + get_frame_size ( ) + crtl -> args . pretend_args_size ) - crtl -> args . pretend_args_size ) ; break ; default : gcc_unreachable ( ) ; } if ( to == STACK_POINTER_REGNUM ) offset += ALPHA_ROUND ( crtl -> outgoing_args_size ) ; return offset ; } } </s>

FROM is to be eliminated for TO . Return the offset so that TO+offset designates the same location as FROM .


<s> static bool decl_has_samegp ( const_tree decl ) { if ( ! ( * targetm . binds_local_p ) ( decl ) ) return false ; if ( TARGET_EXPLICIT_RELOCS && TARGET_SMALL_DATA ) return true ; return ! TREE_PUBLIC ( decl ) || ! DECL_EXTERNAL ( decl ) ; } </s>

Return true if the function DECL will share the same GP as any function in the current unit of translation .


<s> bool direct_return ( void ) { return ( TARGET_ABI_OSF && reload_completed && cfun -> machine -> frame_size == 0 ) ; } </s>

Return non-zero if this function is known to have a null epilogue .


<s> static void emit_frame_store_1 ( rtx value , rtx base_reg , HOST_WIDE_INT frame_bias , HOST_WIDE_INT base_ofs , rtx frame_reg ) { rtx addr , mem ; rtx_insn * insn ; addr = plus_constant ( Pmode , base_reg , base_ofs ) ; mem = gen_frame_mem ( DImode , addr ) ; insn = emit_move_insn ( mem , value ) ; RTX_FRAME_RELATED_P ( insn ) = 1 ; if ( frame_bias || value != frame_reg ) { if ( frame_bias ) { addr = plus_constant ( Pmode , stack_pointer_rtx , frame_bias + base_ofs ) ; mem = gen_rtx_MEM ( DImode , addr ) ; } add_reg_note ( insn , REG_FRAME_RELATED_EXPR , gen_rtx_SET ( mem , frame_reg ) ) ; } } </s>

Generates a store with the proper unwind info attached . VALUE is stored at BASE_REG+BASE_OFS . If FRAME_BIAS is nonzero , then BASE_REG contains SP+FRAME_BIAS , and that is the unwind info that should be generated . If FRAME_REG ! = VALUE , then VALUE is being stored on behalf of FRAME_REG , and FRAME_REG should be present in the unwind .


<s> static rtx emit_insxl ( machine_mode mode , rtx op1 , rtx op2 ) { rtx ret = gen_reg_rtx ( DImode ) ; rtx ( * fn ) ( rtx , rtx , rtx ) ; switch ( mode ) { case E_QImode : fn = gen_insbl ; break ; case E_HImode : fn = gen_inswl ; break ; case E_SImode : fn = gen_insll ; break ; case E_DImode : fn = gen_insql ; break ; default : gcc_unreachable ( ) ; } op1 = force_reg ( mode , op1 ) ; emit_insn ( fn ( ret , op1 , op2 ) ) ; return ret ; } </s>

A subroutine of the atomic operation splitters . Emit an insxl instruction in MODE .


<s> static void emit_unlikely_jump ( rtx cond , rtx label ) { rtx x = gen_rtx_IF_THEN_ELSE ( VOIDmode , cond , label , pc_rtx ) ; rtx_insn * insn = emit_jump_insn ( gen_rtx_SET ( pc_rtx , x ) ) ; add_reg_br_prob_note ( insn , profile_probability :: very_unlikely ( ) ) ; } </s>

Mark the previous jump instruction as unlikely .


<s> virtual unsigned int execute ( function * ) { return rest_of_align_insns ( ) ; } </s>


<s> void get_aligned_mem ( rtx ref , rtx * paligned_mem , rtx * pbitnum ) { rtx base ; HOST_WIDE_INT disp , offset ; gcc_assert ( MEM_P ( ref ) ) ; if ( reload_in_progress ) { base = find_replacement ( & XEXP ( ref , 0 ) ) ; gcc_assert ( memory_address_p ( GET_MODE ( ref ) , base ) ) ; } else base = XEXP ( ref , 0 ) ; if ( GET_CODE ( base ) == PLUS ) disp = INTVAL ( XEXP ( base , 1 ) ) , base = XEXP ( base , 0 ) ; else disp = 0 ; if ( MEM_ALIGN ( ref ) >= 32 ) offset = 0 ; else offset = disp & 3 ; gcc_assert ( offset + GET_MODE_SIZE ( GET_MODE ( ref ) ) <= GET_MODE_SIZE ( SImode ) ) ; * paligned_mem = widen_memory_access ( ref , SImode , - offset ) ; offset *= BITS_PER_UNIT ; * pbitnum = GEN_INT ( offset ) ; } </s>

REF is an alignable memory location . Place an aligned SImode reference into * PALIGNED_MEM and the number of bits to shift into * PBITNUM . SCRATCH is a free register for use in reloading out of range stack slots .


<s> static const char * get_round_mode_suffix ( void ) { enum attr_round_suffix s = get_attr_round_suffix ( current_output_insn ) ; switch ( s ) { case ROUND_SUFFIX_NONE : return NULL ; case ROUND_SUFFIX_NORMAL : switch ( alpha_fprm ) { case ALPHA_FPRM_NORM : return NULL ; case ALPHA_FPRM_MINF : return "m" ; case ALPHA_FPRM_CHOP : return "c" ; case ALPHA_FPRM_DYN : return "d" ; default : gcc_unreachable ( ) ; } break ; case ROUND_SUFFIX_C : return "c" ; default : gcc_unreachable ( ) ; } gcc_unreachable ( ) ; } </s>

Return the rounding mode suffix applicable to the current instruction , or NULL .


<s> static const char * get_trap_mode_suffix ( void ) { enum attr_trap_suffix s = get_attr_trap_suffix ( current_output_insn ) ; switch ( s ) { case TRAP_SUFFIX_NONE : return NULL ; case TRAP_SUFFIX_SU : if ( alpha_fptm >= ALPHA_FPTM_SU ) return "su" ; return NULL ; case TRAP_SUFFIX_SUI : if ( alpha_fptm >= ALPHA_FPTM_SUI ) return "sui" ; return NULL ; case TRAP_SUFFIX_V_SV : switch ( alpha_fptm ) { case ALPHA_FPTM_N : return NULL ; case ALPHA_FPTM_U : return "v" ; case ALPHA_FPTM_SU : case ALPHA_FPTM_SUI : return "sv" ; default : gcc_unreachable ( ) ; } case TRAP_SUFFIX_V_SV_SVI : switch ( alpha_fptm ) { case ALPHA_FPTM_N : return NULL ; case ALPHA_FPTM_U : return "v" ; case ALPHA_FPTM_SU : return "sv" ; case ALPHA_FPTM_SUI : return "svi" ; default : gcc_unreachable ( ) ; } break ; case TRAP_SUFFIX_U_SU_SUI : switch ( alpha_fptm ) { case ALPHA_FPTM_N : return NULL ; case ALPHA_FPTM_U : return "u" ; case ALPHA_FPTM_SU : return "su" ; case ALPHA_FPTM_SUI : return "sui" ; default : gcc_unreachable ( ) ; } break ; default : gcc_unreachable ( ) ; } gcc_unreachable ( ) ; } </s>

Return the trap mode suffix applicable to the current instruction , or NULL .

alpha "su" "sui" "v" "sv" "v" "sv" "svi" "u" "su" "sui"


<s> rtx get_unaligned_address ( rtx ref ) { rtx base ; HOST_WIDE_INT offset = 0 ; gcc_assert ( MEM_P ( ref ) ) ; if ( reload_in_progress ) { base = find_replacement ( & XEXP ( ref , 0 ) ) ; gcc_assert ( memory_address_p ( GET_MODE ( ref ) , base ) ) ; } else base = XEXP ( ref , 0 ) ; if ( GET_CODE ( base ) == PLUS ) offset += INTVAL ( XEXP ( base , 1 ) ) , base = XEXP ( base , 0 ) ; return plus_constant ( Pmode , base , offset ) ; } </s>

Similar , but just get the address . Handle the two reload cases . Add EXTRA_OFFSET to the address we return .


<s> rtx get_unaligned_offset ( rtx addr , HOST_WIDE_INT ofs ) { if ( GET_CODE ( addr ) == PLUS ) { ofs += INTVAL ( XEXP ( addr , 1 ) ) ; addr = XEXP ( addr , 0 ) ; } return expand_simple_binop ( Pmode , PLUS , addr , GEN_INT ( ofs & 7 ) , NULL_RTX , 1 , OPTAB_LIB_WIDEN ) ; } </s>

Compute a value X , such that X & 7 == ( ADDR + OFS ) & 7 . X is always returned in a register .


<s> rtx resolve_reload_operand ( rtx op ) { if ( reload_in_progress ) { rtx tmp = op ; if ( SUBREG_P ( tmp ) ) tmp = SUBREG_REG ( tmp ) ; if ( REG_P ( tmp ) && REGNO ( tmp ) >= FIRST_PSEUDO_REGISTER ) { op = reg_equiv_memory_loc ( REGNO ( tmp ) ) ; if ( op == 0 ) return 0 ; } } return op ; } </s>

Used by aligned_memory_operand and unaligned_memory_operand to resolve what reload is going to do with OP if it 's a register .


<s> static rtx_insn * set_frame_related_p ( void ) { rtx_insn * seq = get_insns ( ) ; rtx_insn * insn ; end_sequence ( ) ; if ( ! seq ) return NULL ; if ( INSN_P ( seq ) ) { insn = seq ; while ( insn != NULL_RTX ) { RTX_FRAME_RELATED_P ( insn ) = 1 ; insn = NEXT_INSN ( insn ) ; } seq = emit_insn ( seq ) ; } else { seq = emit_insn ( seq ) ; RTX_FRAME_RELATED_P ( seq ) = 1 ; } return seq ; } </s>

Helper function to set RTX_FRAME_RELATED_P on instructions , including sequences .


<s> int tls_symbolic_operand_1 ( rtx op , int size , int unspec ) { op = XEXP ( op , 0 ) ; if ( GET_CODE ( op ) != UNSPEC || XINT ( op , 1 ) != unspec ) return 0 ; op = XVECEXP ( op , 0 , 0 ) ; if ( GET_CODE ( op ) != SYMBOL_REF ) return 0 ; switch ( SYMBOL_REF_TLS_MODEL ( op ) ) { case TLS_MODEL_LOCAL_DYNAMIC : return unspec == UNSPEC_DTPREL && size == alpha_tls_size ; case TLS_MODEL_INITIAL_EXEC : return unspec == UNSPEC_TPREL && size == 64 ; case TLS_MODEL_LOCAL_EXEC : return unspec == UNSPEC_TPREL && size == alpha_tls_size ; default : gcc_unreachable ( ) ; } } </s>

Return true if OP is valid for a particular TLS relocation . We are already guaranteed that OP is a CONST .


<s> static enum tls_model tls_symbolic_operand_type ( rtx symbol ) { enum tls_model model ; if ( GET_CODE ( symbol ) != SYMBOL_REF ) return TLS_MODEL_NONE ; model = SYMBOL_REF_TLS_MODEL ( symbol ) ; if ( model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64 ) model = TLS_MODEL_INITIAL_EXEC ; return model ; } </s>

Return the TLS model to use for SYMBOL .


<s> static gimple * va_list_skip_additions ( tree lhs ) { gimple * stmt ; for ( ; ; ) { enum tree_code code ; stmt = SSA_NAME_DEF_STMT ( lhs ) ; if ( gimple_code ( stmt ) == GIMPLE_PHI ) return stmt ; if ( ! is_gimple_assign ( stmt ) || gimple_assign_lhs ( stmt ) != lhs ) return NULL ; if ( TREE_CODE ( gimple_assign_rhs1 ( stmt ) ) != SSA_NAME ) return stmt ; code = gimple_assign_rhs_code ( stmt ) ; if ( ! CONVERT_EXPR_CODE_P ( code ) && ( ( code != PLUS_EXPR && code != POINTER_PLUS_EXPR ) || TREE_CODE ( gimple_assign_rhs2 ( stmt ) ) != INTEGER_CST || ! tree_fits_uhwi_p ( gimple_assign_rhs2 ( stmt ) ) ) ) return stmt ; lhs = gimple_assign_rhs1 ( stmt ) ; } } </s>

Helper function for alpha_stdarg_optimize_hook . Skip over casts and constant additions .


<s> static void vms_asm_named_section ( const char * name , unsigned int flags , tree decl ATTRIBUTE_UNUSED ) { fputc ( '\n' , asm_out_file ) ; fprintf ( asm_out_file , ".section\t%s" , name ) ; if ( flags & SECTION_DEBUG ) fprintf ( asm_out_file , ",NOWRT" ) ; fputc ( '\n' , asm_out_file ) ; } </s>

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 .


<s> static void vms_asm_out_constructor ( rtx symbol , int priority ATTRIBUTE_UNUSED ) { switch_to_section ( ctors_section ) ; assemble_align ( BITS_PER_WORD ) ; assemble_integer ( symbol , UNITS_PER_WORD , BITS_PER_WORD , 1 ) ; } </s>


<s> int zap_mask ( HOST_WIDE_INT value ) { int i ; for ( i = 0 ; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR ; i ++ , value >>= 8 ) if ( ( value & 0xff ) != 0 && ( value & 0xff ) != 0xff ) return 0 ; return 1 ; } </s>

Returns 1 if VALUE is a mask that contains full bytes of zero or ones .


<s> const char * host_detect_local_cpu ( int argc , const char * * argv ) { static const struct cpu_types { long implver ; long amask ; const char * const cpu ; } cpu_types [ ] = { { IMPLVER_EV7_FAMILY , AMASK_BWX | AMASK_MVI | AMASK_FIX | AMASK_CIX , "ev67" } , { IMPLVER_EV6_FAMILY , AMASK_BWX | AMASK_MVI | AMASK_FIX | AMASK_CIX , "ev67" } , { IMPLVER_EV6_FAMILY , AMASK_BWX | AMASK_MVI | AMASK_FIX , "ev6" } , { IMPLVER_EV5_FAMILY , AMASK_BWX | AMASK_MVI , "pca56" } , { IMPLVER_EV5_FAMILY , AMASK_BWX , "ev56" } , { IMPLVER_EV5_FAMILY , 0 , "ev5" } , { IMPLVER_EV4_FAMILY , 0 , "ev4" } , { 0 , 0 , NULL } } ; long implver ; long amask ; const char * cpu ; int i ; if ( argc < 1 ) return NULL ; if ( strcmp ( argv [ 0 ] , "cpu" ) && strcmp ( argv [ 0 ] , "tune" ) ) return NULL ; implver = __builtin_alpha_implver ( ) ; amask = __builtin_alpha_amask ( ~ 0L ) ; cpu = NULL ; for ( i = 0 ; cpu_types [ i ] . cpu != NULL ; i ++ ) if ( implver == cpu_types [ i ] . implver && ( ~ amask & cpu_types [ i ] . amask ) == cpu_types [ i ] . amask ) { cpu = cpu_types [ i ] . cpu ; break ; } if ( cpu == NULL ) return NULL ; return concat ( "-m" , argv [ 0 ] , "=" , cpu , NULL ) ; } </s>

This will be called by the spec parser in gcc.cc when it sees a % : local_cpu_detect ( args ) construct . Currently it will be called with either `` cpu '' or `` tune '' as argument depending on if -mcpu=native or -mtune=native is to be substituted . It returns a string containing new command line parameters to be put at the place of the above two options , depending on what CPU this is executed . E.g . `` -mcpu=ultrasparc3 '' on an UltraSPARC III for -mcpu=native . If the routine ca n't detect a known processor , the -mcpu or -mtune option is discarded . ARGC and ARGV are set depending on the actual arguments given in the spec .


<s> static void addarg ( const char * str ) { int i ; if ( ++ comp_arg_index >= comp_arg_max ) { const char * * new_comp_args = ( const char * * ) xcalloc ( comp_arg_max + 1000 , sizeof ( char * ) ) ; for ( i = 0 ; i <= comp_arg_max ; i ++ ) new_comp_args [ i ] = comp_args [ i ] ; if ( comp_args ) free ( comp_args ) ; comp_arg_max += 1000 ; comp_args = new_comp_args ; } comp_args [ comp_arg_index ] = str ; } </s>

Append STR to the command line to invoke the linker . Expand the line as necessary to accommodate .


<s> static void preprocess_args ( int * p_argc , char * argv [ ] ) { int i ; for ( i = 1 ; i < * p_argc ; i ++ ) { if ( strcmp ( argv [ i ] , "-o" ) == 0 ) { char * buff , * ptr ; i ++ ; ptr = to_host_file_spec ( argv [ i ] ) ; objfilename = xstrdup ( ptr ) ; buff = concat ( "/obj=" , ptr , NULL ) ; addarg ( buff ) ; } } } </s>

Preprocess the number of args P_ARGC in ARGV . Look for special flags , etc . that must be handled first .


<s> static void process_args ( int * p_argc , char * argv [ ] ) { int i ; for ( i = 1 ; i < * p_argc ; i ++ ) { if ( strlen ( argv [ i ] ) < 2 ) continue ; if ( strncmp ( argv [ i ] , "-I" , 2 ) == 0 ) { char * ptr ; int new_len , search_dirs_len ; ptr = to_host_dir_spec ( & argv [ i ] [ 2 ] ) ; new_len = strlen ( ptr ) ; search_dirs_len = strlen ( search_dirs ) ; search_dirs = xrealloc ( search_dirs , search_dirs_len + new_len + 2 ) ; if ( search_dirs_len > 0 ) strcat ( search_dirs , PATH_SEPARATOR_STR ) ; strcat ( search_dirs , ptr ) ; } else if ( strncmp ( argv [ i ] , "-D" , 2 ) == 0 ) { char * ptr ; int new_len , defines_len ; ptr = & argv [ i ] [ 2 ] ; new_len = strlen ( ptr ) ; defines_len = strlen ( defines ) ; defines = xrealloc ( defines , defines_len + new_len + 4 ) ; if ( defines_len > 0 ) strcat ( defines , "," ) ; strcat ( defines , "\"" ) ; strcat ( defines , ptr ) ; strcat ( defines , "\"" ) ; } else if ( strcmp ( argv [ i ] , "-v" ) == 0 ) verbose = 1 ; else if ( strcmp ( argv [ i ] , "-g0" ) == 0 ) addarg ( "/nodebug" ) ; else if ( strcmp ( argv [ i ] , "-O0" ) == 0 ) addarg ( "/noopt" ) ; else if ( strncmp ( argv [ i ] , "-g" , 2 ) == 0 ) addarg ( "/debug" ) ; else if ( strcmp ( argv [ i ] , "-E" ) == 0 ) addarg ( "/preprocess" ) ; else if ( strcmp ( argv [ i ] , "-save-temps" ) == 0 ) save_temps = 1 ; } } </s>

Preprocess the number of args ARGC in ARGV . Look for special flags , etc . that must be handled for the VMS linker .


<s> static char * to_host_file_spec ( char * filespec ) { strcpy ( new_host_filespec , "" ) ; if ( strchr ( filespec , ']' ) || strchr ( filespec , ':' ) ) strcpy ( new_host_filespec , filespec ) ; else { decc$to_vms ( filespec , translate_unix , 1 , 1 ) ; strcpy ( new_host_filespec , filename_buff ) ; } return new_host_filespec ; } </s>

Translate a Unix syntax file specification FILESPEC into VMS syntax . If indicators of VMS syntax found , return input string . Return a pointer to a static buffer .


<s> static int translate_unix ( char * name , int type ATTRIBUTE_UNUSED ) { strcpy ( filename_buff , name ) ; return 0 ; } </s>

Action routine called by decc $ to_vms . NAME is a file name or directory name . TYPE is unused .


<s> static void addarg ( const char * str ) { int i ; if ( ++ link_arg_index >= link_arg_max ) { const char * * new_link_args = ( const char * * ) xcalloc ( link_arg_max + 1000 , sizeof ( char * ) ) ; for ( i = 0 ; i <= link_arg_max ; i ++ ) new_link_args [ i ] = link_args [ i ] ; if ( link_args ) free ( link_args ) ; link_arg_max += 1000 ; link_args = new_link_args ; } link_args [ link_arg_index ] = str ; } </s>


"Couldn't locate library: lib%s.exe, lib%s.a or lib%s.olb\n"

Given a library name NAME , i.e . foo , Look for libfoo.lib and then libfoo.a in the set of directories we are allowed to search in . May return NULL if the library can be discarded .


<s> static int is_regular_file ( char * name ) { int ret ; struct stat statbuf ; ret = stat ( name , & statbuf ) ; return ! ret && S_ISREG ( statbuf . st_mode ) ; } </s>

Check to see if NAME is a regular file , i.e . not a directory .


<s> static char * locate_lib ( char * lib_name , char * path_val ) { int lib_len = strlen ( lib_name ) ; char * eptr , * sptr ; for ( sptr = path_val ; * sptr ; sptr = eptr ) { char * buf , * ptr ; while ( * sptr == PATH_SEPARATOR ) sptr ++ ; eptr = strchr ( sptr , PATH_SEPARATOR ) ; if ( eptr == 0 ) eptr = strchr ( sptr , 0 ) ; buf = alloca ( ( eptr - sptr ) + lib_len + 4 + 2 ) ; strncpy ( buf , sptr , eptr - sptr ) ; buf [ eptr - sptr ] = 0 ; strcat ( buf , "/" ) ; strcat ( buf , lib_name ) ; ptr = strchr ( buf , 0 ) ; if ( debug || staticp ) { strcpy ( ptr , ".a" ) ; if ( is_regular_file ( buf ) ) return xstrdup ( to_host_file_spec ( buf ) ) ; strcpy ( ptr , ".olb" ) ; if ( is_regular_file ( buf ) ) return xstrdup ( to_host_file_spec ( buf ) ) ; strcpy ( ptr , ".exe" ) ; if ( is_regular_file ( buf ) ) return xstrdup ( to_host_file_spec ( buf ) ) ; } else { strcpy ( ptr , ".exe" ) ; if ( is_regular_file ( buf ) ) return xstrdup ( to_host_file_spec ( buf ) ) ; strcpy ( ptr , ".a" ) ; if ( is_regular_file ( buf ) ) return xstrdup ( to_host_file_spec ( buf ) ) ; strcpy ( ptr , ".olb" ) ; if ( is_regular_file ( buf ) ) return xstrdup ( to_host_file_spec ( buf ) ) ; } } return 0 ; } </s>

Locate library LIB_NAME on the library path .


<s> static void preprocess_args ( int * p_argc , char * * argv ) { int i ; for ( i = 1 ; i < * p_argc ; i ++ ) if ( strlen ( argv [ i ] ) >= 6 && strncmp ( argv [ i ] , "-shared" , 7 ) == 0 ) share = 1 ; for ( i = 1 ; i < * p_argc ; i ++ ) if ( strcmp ( argv [ i ] , "-o" ) == 0 ) { char * buff , * ptr ; int out_len ; int len ; i ++ ; ptr = to_host_file_spec ( argv [ i ] ) ; exefilename = xstrdup ( ptr ) ; out_len = strlen ( ptr ) ; buff = xmalloc ( out_len + 18 ) ; if ( share ) strcpy ( buff , "/share=" ) ; else strcpy ( buff , "/exe=" ) ; strcat ( buff , ptr ) ; addarg ( buff ) ; if ( share ) { sharefilename = xmalloc ( out_len + 5 ) ; if ( ptr == strchr ( argv [ i ] , ']' ) ) strcpy ( sharefilename , ++ ptr ) ; else if ( ptr == strchr ( argv [ i ] , ':' ) ) strcpy ( sharefilename , ++ ptr ) ; else if ( ptr == strrchr ( argv [ i ] , '/' ) ) strcpy ( sharefilename , ++ ptr ) ; else strcpy ( sharefilename , argv [ i ] ) ; len = strlen ( sharefilename ) ; if ( strncasecmp ( & sharefilename [ len - 4 ] , ".exe" , 4 ) == 0 ) sharefilename [ len - 4 ] = 0 ; for ( ptr = sharefilename ; * ptr ; ptr ++ ) * ptr = TOUPPER ( * ptr ) ; } } } </s>


<s> static void process_args ( int * p_argc , char * * argv ) { int i ; for ( i = 1 ; i < * p_argc ; i ++ ) { if ( strlen ( argv [ i ] ) < 2 ) continue ; if ( strncmp ( argv [ i ] , "-L" , 2 ) == 0 ) { char * nbuff , * ptr ; int new_len , search_dirs_len ; ptr = & argv [ i ] [ 2 ] ; new_len = strlen ( ptr ) ; search_dirs_len = strlen ( search_dirs ) ; nbuff = xmalloc ( new_len + 1 ) ; strcpy ( nbuff , ptr ) ; while ( new_len > 1 && nbuff [ new_len - 1 ] == '/' ) { nbuff [ new_len - 1 ] = 0 ; new_len -- ; } search_dirs = xrealloc ( search_dirs , search_dirs_len + new_len + 2 ) ; if ( search_dirs_len > 0 ) strcat ( search_dirs , PATH_SEPARATOR_STR ) ; strcat ( search_dirs , nbuff ) ; free ( nbuff ) ; } else if ( strcmp ( argv [ i ] , "-v" ) == 0 ) verbose = 1 ; else if ( strcmp ( argv [ i ] , "-g0" ) == 0 ) addarg ( "/notraceback" ) ; else if ( strncmp ( argv [ i ] , "-g" , 2 ) == 0 ) { addarg ( "/debug" ) ; debug = 1 ; } else if ( strcmp ( argv [ i ] , "-static" ) == 0 ) staticp = 1 ; else if ( strcmp ( argv [ i ] , "-map" ) == 0 ) { char * buff , * ptr ; buff = xmalloc ( strlen ( exefilename ) + 5 ) ; strcpy ( buff , exefilename ) ; ptr = strchr ( buff , '.' ) ; if ( ptr ) * ptr = 0 ; strcat ( buff , ".map" ) ; addarg ( "/map=" ) ; addarg ( buff ) ; addarg ( "/full" ) ; } else if ( strcmp ( argv [ i ] , "-save-temps" ) == 0 ) save_temps = 1 ; else if ( strcmp ( argv [ i ] , "--noinhibit-exec" ) == 0 ) inhibit_exec = 0 ; } } </s>