@@ -105,10 +105,12 @@ struct GTY (()) arc64_frame
105
105
typedef struct GTY (( )) machine_function
106
106
{
107
107
struct arc64_frame frame ;
108
+ /* Record if the function has a variable argument list. */
109
+ int uses_anonymous_args ;
108
110
} machine_function ;
109
111
110
112
/* ALIGN FRAMES on word boundaries. */
111
- #define ARC_STACK_ALIGN (LOC ) \
113
+ #define ARC64_STACK_ALIGN (LOC ) \
112
114
(((LOC) + STACK_BOUNDARY / BITS_PER_UNIT - 1) & -STACK_BOUNDARY/BITS_PER_UNIT)
113
115
114
116
/* Round CUM up to the necessary point for argument MODE/TYPE. */
@@ -229,27 +231,24 @@ arc64_compute_frame_info (void)
229
231
230
232
/* 1. At the bottom of the stack are any outgoing stack
231
233
arguments. */
232
- frame -> saved_outargs_size = ROUND_UP (crtl -> outgoing_args_size ,
233
- STACK_BOUNDARY / BITS_PER_UNIT );
234
+ frame -> saved_outargs_size = ARC64_STACK_ALIGN (crtl -> outgoing_args_size );
234
235
235
236
/* 2. Size of locals and temporaries. */
236
- frame -> saved_locals_size = ROUND_UP (get_frame_size (),
237
- STACK_BOUNDARY / BITS_PER_UNIT );
237
+ frame -> saved_locals_size = ARC64_STACK_ALIGN (get_frame_size ());
238
238
239
239
/* 3. Size of the saved registers (including FP/BLINK).
240
240
FIXME! FPR registers. */
241
- frame -> saved_regs_size = ROUND_UP (offset ,
242
- STACK_BOUNDARY / BITS_PER_UNIT );
241
+ frame -> saved_regs_size = ARC64_STACK_ALIGN (offset );
243
242
244
243
/* 4. Size of the callee-allocated area for pretend stack
245
244
arguments. */
246
- frame -> saved_varargs_size = ROUND_UP (crtl -> args .pretend_args_size ,
247
- STACK_BOUNDARY / BITS_PER_UNIT );
245
+ frame -> saved_varargs_size = ARC64_STACK_ALIGN (crtl -> args .pretend_args_size );
248
246
249
247
/* Total size. */
250
248
frame -> frame_size = frame -> saved_outargs_size + frame -> saved_locals_size
251
249
+ frame -> saved_regs_size + frame -> saved_varargs_size ;
252
250
251
+ gcc_assert (frame -> frame_size == ARC64_STACK_ALIGN (frame -> frame_size ));
253
252
frame -> layout_p = reload_completed ;
254
253
}
255
254
@@ -693,6 +692,7 @@ arc64_setup_incoming_varargs (cumulative_args_t cum_v, machine_mode mode,
693
692
argument, to find out how many registers are left over. */
694
693
arc64_function_arg_advance (pack_cumulative_args (& cum ), mode , type , true);
695
694
695
+ cfun -> machine -> uses_anonymous_args = 1 ;
696
696
if (!FUNCTION_ARG_REGNO_P (cum ))
697
697
return ;
698
698
@@ -1091,6 +1091,7 @@ arc64_legitimize_address_1 (rtx x, rtx scratch)
1091
1091
a trampoline, leaving space for variable parts. A trampoline looks
1092
1092
like this:
1093
1093
1094
+ nop
1094
1095
ldl r12,[pcl,12]
1095
1096
ldl r11,[pcl,16]
1096
1097
j [r12]
@@ -1102,6 +1103,7 @@ arc64_legitimize_address_1 (rtx x, rtx scratch)
1102
1103
static void
1103
1104
arc64_asm_trampoline_template (FILE * f )
1104
1105
{
1106
+ asm_fprintf (f , "\tnop\n" );
1105
1107
asm_fprintf (f , "\tldl\t%s,[pcl,12]\n" , reg_names [12 ]);
1106
1108
asm_fprintf (f , "\tldl\t%s,[pcl,16]\n" , reg_names [STATIC_CHAIN_REGNUM ]);
1107
1109
asm_fprintf (f , "\tj\t[%s]\n" , reg_names [12 ]);
@@ -1118,8 +1120,8 @@ arc64_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
1118
1120
1119
1121
emit_block_move (tramp , assemble_trampoline_template (),
1120
1122
GEN_INT (TRAMPOLINE_SIZE ), BLOCK_OP_NORMAL );
1121
- emit_move_insn (adjust_address (tramp , Pmode , 12 ), fnaddr );
1122
- emit_move_insn (adjust_address (tramp , Pmode , 20 ), cxt );
1123
+ emit_move_insn (adjust_address (tramp , Pmode , 12 + 4 ), fnaddr );
1124
+ emit_move_insn (adjust_address (tramp , Pmode , 20 + 4 ), cxt );
1123
1125
emit_library_call (gen_rtx_SYMBOL_REF (Pmode , "__clear_cache" ),
1124
1126
LCT_NORMAL , VOIDmode , XEXP (tramp , 0 ), Pmode ,
1125
1127
plus_constant (Pmode , XEXP (tramp , 0 ), TRAMPOLINE_SIZE ),
@@ -1147,6 +1149,132 @@ arc64_init_libfuncs (void)
1147
1149
set_optab_libfunc (parity_optab , SImode , "__paritysi2" );
1148
1150
}
1149
1151
1152
+ /* Helper evp_dump_stack_info. */
1153
+
1154
+ static void
1155
+ arc64_print_format_registers (FILE * stream ,
1156
+ unsigned regno ,
1157
+ enum machine_mode mode )
1158
+ {
1159
+ unsigned int j , nregs = arc64_hard_regno_nregs (regno , mode );
1160
+ unsigned int ll = 0 ;
1161
+ for (j = regno + nregs ; j > regno ; j -- )
1162
+ {
1163
+ asm_fprintf (stream ,"%s" , reg_names [j - 1 ]);
1164
+ ll += strlen (reg_names [j - 1 ]);
1165
+ }
1166
+ asm_fprintf (stream ,"`" );
1167
+ for (j = ll ; j < 20 ; j ++ )
1168
+ asm_fprintf (stream , " " );
1169
+
1170
+ asm_fprintf (stream ,"\t(%d)\n" ,
1171
+ GET_MODE_SIZE (mode ));
1172
+ }
1173
+
1174
+ /* Place some comment into assembler stream describing the current
1175
+ function. */
1176
+
1177
+ static void
1178
+ arc64_output_function_prologue (FILE * f )
1179
+ {
1180
+ int regno , i ;
1181
+ struct arc64_frame * frame = & cfun -> machine -> frame ;
1182
+ tree parm = DECL_ARGUMENTS (current_function_decl );
1183
+
1184
+ asm_fprintf (f , "\t# args = %wd, pretend = %ld, frame = %wd\n" ,
1185
+ (HOST_WIDE_INT ) crtl -> args .size ,
1186
+ frame -> saved_varargs_size ,
1187
+ (HOST_WIDE_INT ) get_frame_size ());
1188
+ asm_fprintf (f , "\t# frame_needed = %d, uses_anonymous_args = %d\n" ,
1189
+ frame_pointer_needed ,
1190
+ cfun -> machine -> uses_anonymous_args );
1191
+ asm_fprintf (f , "\t# size = %wd bytes\n" ,
1192
+ frame -> frame_size );
1193
+ asm_fprintf (f , "\t# outargs = %wd bytes\n" ,
1194
+ frame -> saved_outargs_size );
1195
+ asm_fprintf (f , "\t# locals = %wd bytes\n" ,
1196
+ frame -> saved_locals_size );
1197
+ asm_fprintf (f , "\t# regs = %wd bytes\n" ,
1198
+ frame -> saved_regs_size );
1199
+ asm_fprintf (f , "\t# varargs = %wd bytes\n" ,
1200
+ frame -> saved_varargs_size );
1201
+
1202
+ if (crtl -> calls_eh_return )
1203
+ asm_fprintf (f , "\t# Calls __builtin_eh_return.\n" );
1204
+
1205
+ for (regno = R0_REGNUM ; regno <= R59_REGNUM ; regno ++ )
1206
+ if (frame -> reg_offset [regno ] != -1 )
1207
+ asm_fprintf (f , "\t# regsave[%s] => %ld\n" , reg_names [regno ],
1208
+ frame -> reg_offset [regno ]);
1209
+
1210
+ asm_fprintf (f , "\t# Parameters:\n" );
1211
+ while (parm )
1212
+ {
1213
+ rtx rtl = DECL_INCOMING_RTL (parm );
1214
+ if (rtl )
1215
+ {
1216
+ asm_fprintf (f ,"\t# " );
1217
+ tree decl_name ;
1218
+ decl_name = DECL_NAME (parm );
1219
+ if (decl_name != NULL && IDENTIFIER_POINTER (decl_name ) != NULL )
1220
+ {
1221
+ const char * name = lang_hooks .dwarf_name (parm , 0 );
1222
+ if (name )
1223
+ asm_fprintf (f , "%-20.20s =`" , name );
1224
+ else
1225
+ asm_fprintf (f , "N.A.`" );
1226
+ }
1227
+ if (REG_P (rtl ))
1228
+ {
1229
+ unsigned regno = REGNO (rtl );
1230
+ enum machine_mode mode = GET_MODE (rtl );
1231
+ arc64_print_format_registers (f , regno , mode );
1232
+ }
1233
+ else if (MEM_P (rtl ))
1234
+ {
1235
+ rtx addr = XEXP (rtl , 0 );
1236
+ long argPtrOfs = frame -> frame_size -
1237
+ arc64_initial_elimination_offset (ARG_POINTER_REGNUM ,
1238
+ (frame_pointer_needed ?
1239
+ HARD_FRAME_POINTER_REGNUM :
1240
+ STACK_POINTER_REGNUM ));
1241
+ if (GET_CODE (addr ) == PLUS )
1242
+ {
1243
+ rtx ofs = XEXP (addr , 1 );
1244
+ gcc_assert (CONST_INT_P (ofs ));
1245
+ argPtrOfs += INTVAL (ofs );
1246
+ }
1247
+ asm_fprintf (f , "%s[%4ld]` (%d)\n" ,
1248
+ (frame_pointer_needed ? "fp" : "sp" ),
1249
+ argPtrOfs ,
1250
+ GET_MODE_SIZE (GET_MODE (rtl )));
1251
+ }
1252
+ else if (GET_CODE (rtl ) == PARALLEL )
1253
+ {
1254
+ asm_fprintf (f ,"xvec` (%d)\n" ,
1255
+ GET_MODE_SIZE (GET_MODE (rtl )));
1256
+ for (i = 0 ; i < XVECLEN (rtl , 0 ); i ++ )
1257
+ {
1258
+ rtx xv = XEXP (XVECEXP (rtl , 0 , i ), 0 );
1259
+ if (REG_P (xv ))
1260
+ {
1261
+ unsigned regno = REGNO (xv );
1262
+ enum machine_mode mode = GET_MODE (xv );
1263
+ asm_fprintf (f ,"# `" );
1264
+ arc64_print_format_registers (f , regno , mode );
1265
+ }
1266
+ }
1267
+ }
1268
+ else
1269
+ {
1270
+ asm_fprintf (f ,"N.A. `\n" );
1271
+ }
1272
+ }
1273
+ parm = TREE_CHAIN (parm );
1274
+ }
1275
+ }
1276
+
1277
+
1150
1278
/*
1151
1279
Global functions.
1152
1280
*/
@@ -1630,6 +1758,9 @@ arc64_limm_addr_p (rtx op)
1630
1758
#undef TARGET_ASM_FILE_END
1631
1759
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
1632
1760
1761
+ #undef TARGET_ASM_FUNCTION_PROLOGUE
1762
+ #define TARGET_ASM_FUNCTION_PROLOGUE arc64_output_function_prologue
1763
+
1633
1764
struct gcc_target targetm = TARGET_INITIALIZER ;
1634
1765
1635
1766
#include "gt-arc64.h"
0 commit comments