00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "defs.h"
00037 #include "tn.h"
00038 #include "op.h"
00039 #include "bb.h"
00040 #include "wn.h"
00041 #include "symtab.h"
00042 #include "errors.h"
00043 #include "targ_sim.h"
00044 #include "ttype.h"
00045 #include "topcode.h"
00046 #include "register.h"
00047 #include "entry_exit_targ.h"
00048 #include "calls.h"
00049 #include "be_util.h"
00050 #include "data_layout.h"
00051 #include "stblock.h"
00052 #include "cgtarget.h"
00053 #include "whirl2ops.h"
00054
00055 void
00056 EETARG_Save_Pfs (TN *saved_pfs, OPS *ops)
00057 {
00058
00059 Build_OP (TOP_alloc, saved_pfs,
00060
00061 Gen_Literal_TN(0, 4),
00062 Gen_Literal_TN(0, 4),
00063 Gen_Literal_TN(0, 4),
00064 Gen_Literal_TN(0, 4),
00065 ops);
00066 }
00067
00068
00069 void
00070 EETARG_Restore_Pfs (TN *saved_pfs, OPS *ops)
00071 {
00072
00073 Build_OP (TOP_mov_t_ar_r_i, Pfs_TN, True_TN, saved_pfs, ops);
00074 }
00075
00076 void
00077 EETARG_Call_Mcount(BB *bb)
00078 {
00079 if (Call_Mcount) {
00080
00081
00082
00083
00084
00085 char data_name[20];
00086 sprintf(data_name, "mcount_data_%d", Current_PU_Count());
00087 ST *data_st = New_ST (GLOBAL_SYMTAB);
00088 ST_Init (data_st, Save_Str(data_name),
00089 CLASS_VAR, SCLASS_FSTATIC,
00090 EXPORT_LOCAL, MTYPE_To_TY(Pointer_Mtype));
00091
00092 Set_ST_is_initialized(data_st);
00093 INITO_IDX ino = New_INITO(data_st);
00094 INITV_IDX inv = New_INITV();
00095 INITV_Init_Integer (inv, Pointer_Mtype, 0);
00096 Set_INITO_val(ino, inv);
00097 Allocate_Object(data_st);
00098
00099
00100 char asm_string[256];
00101 ST *base;
00102 INT64 ofst;
00103 Base_Symbol_And_Offset (data_st, &base, &ofst);
00104 sprintf(asm_string, "%s%s(%s+%lld)%s",
00105 "\talloc out0 = ar.pfs, 8, 0, 4, 0\n"
00106 "\taddl out3 = @",
00107 (ST_gprel(base) ? "gprel" : "ltoff"),
00108 ST_name(base), ofst,
00109 ", gp;;\n"
00110 "\tmov out1 = gp\n"
00111 "\tmov out2 = b0\n"
00112 "\tbr.call.sptk.many b0 = _mcount;;\n");
00113
00114 TN* result[10];
00115 TN* opnd[10];
00116 OP* asm_op = Mk_VarOP(TOP_asm, 0, 0, result, opnd);
00117 Set_OP_volatile(asm_op);
00118
00119 ASM_OP_ANNOT* asm_info = TYPE_PU_ALLOC(ASM_OP_ANNOT);
00120 bzero(asm_info, sizeof(ASM_OP_ANNOT));
00121 WN *asm_wn = WN_CreateAsm_Stmt (0, asm_string);
00122 ASM_OP_wn(asm_info) = asm_wn;
00123 OP_MAP_Set(OP_Asm_Map, asm_op, asm_info);
00124 BB_Prepend_Op (bb, asm_op);
00125
00126 }
00127 }
00128
00129 void
00130 EETARG_Fixup_Entry_Code (BB *bb)
00131 {
00132
00133 OP *op;
00134 INT num_output;
00135 INT num_local;
00136 INT num_rotating;
00137 FOR_ALL_BB_OPs_FWD(bb, op) {
00138 if (OP_code(op) != TOP_alloc) continue;
00139 num_local = REGISTER_Number_Stacked_Local(
00140 ISA_REGISTER_CLASS_integer);
00141 num_output = REGISTER_Number_Stacked_Output(
00142 ISA_REGISTER_CLASS_integer);
00143 num_rotating = REGISTER_Number_Stacked_Rotating(
00144 ISA_REGISTER_CLASS_integer);
00145 num_output = MAX(num_output, num_rotating - num_local);
00146 if (num_local + num_output + num_rotating == 0) {
00147 BB_Remove_Op (bb, op);
00148 }
00149 else {
00150 Set_OP_opnd(op, 1, Gen_Literal_TN(num_local, 4));
00151 Set_OP_opnd(op, 2, Gen_Literal_TN(num_output, 4));
00152 Set_OP_opnd(op, 3, Gen_Literal_TN(num_rotating, 4));
00153 }
00154 return;
00155 }
00156 }
00157
00158 void
00159 EETARG_Init_Entry_Exit_Code (WN *pu_wn, BOOL need_frame_pointer)
00160 {
00161
00162
00163 if (need_frame_pointer && REGISTER_fp == REGISTER_UNDEFINED) {
00164
00165
00166 PLOC ploc;
00167 INT i;
00168 ISA_REGISTER_CLASS rclass;
00169 REGISTER reg;
00170 ploc = Setup_Input_Parameter_Locations(ST_pu_type(WN_st(pu_wn)));
00171 for (i = 0; i < WN_num_formals(pu_wn); i++) {
00172 ploc = Get_Input_Parameter_Location (
00173 TY_Of_Parameter(WN_formal(pu_wn,i)));
00174 if ( ! PLOC_on_stack(ploc)
00175 && CGTARG_Preg_Register_And_Class(
00176 PLOC_reg(ploc), &rclass, ®) )
00177 {
00178 if (ABI_PROPERTY_Is_stacked(
00179 rclass,
00180 REGISTER_machine_id(rclass, reg) ))
00181 {
00182 reg = REGISTER_Allocate_Stacked_Register(
00183 ABI_PROPERTY_callee, rclass, reg);
00184 }
00185 }
00186 }
00187 if (TY_is_varargs (ST_pu_type(WN_st(pu_wn)))) {
00188
00189 if ( PLOC_is_nonempty(ploc) && ! PLOC_on_stack(ploc)) {
00190 ploc = Get_Vararg_Input_Parameter_Location (ploc);
00191 }
00192 while ( ! PLOC_on_stack(ploc)) {
00193 CGTARG_Preg_Register_And_Class(
00194 PLOC_reg(ploc), &rclass, ®);
00195 if (ABI_PROPERTY_Is_stacked(
00196 rclass,
00197 REGISTER_machine_id(rclass, reg) ))
00198 {
00199 reg = REGISTER_Allocate_Stacked_Register(
00200 ABI_PROPERTY_callee, rclass, reg);
00201 }
00202 ploc = Get_Vararg_Input_Parameter_Location (ploc);
00203 }
00204 }
00205 FP_TN = Build_Dedicated_TN (ISA_REGISTER_CLASS_integer,
00206 REGISTER_Request_Stacked_Register(ABI_PROPERTY_frame_ptr,
00207 ISA_REGISTER_CLASS_integer), 0);
00208 }
00209 }
00210
00211 void EETARG_Save_Extra_Callee_Tns (OPS *ops)
00212 {
00213
00214
00215
00216
00217
00218
00219 TN *callee_tn = CALLEE_tn(Callee_Saved_Regs_Count);
00220
00221
00222
00223
00224 if (callee_tn == NULL) {
00225 callee_tn = Build_RCLASS_TN(ISA_REGISTER_CLASS_integer);
00226 Set_TN_is_gra_cannot_split(callee_tn);
00227 CALLEE_tn(Callee_Saved_Regs_Count) = callee_tn;
00228 }
00229 Build_OP (TOP_mov_f_pr, callee_tn, True_TN, ops);
00230 Set_OP_no_move_before_gra(OPS_last(ops));
00231 }
00232
00233 void EETARG_Restore_Extra_Callee_Tns (OPS *ops)
00234 {
00235
00236 TN *callee_tn = CALLEE_tn(Callee_Saved_Regs_Count);
00237 Build_OP (TOP_mov_t_pr, True_TN, callee_tn, Gen_Literal_TN(-1, 4), ops);
00238 Set_OP_no_move_before_gra(OPS_last(ops));
00239 }
00240
00241
00242 OP *
00243 EETARG_Build_Jump_Instead_Of_Call (OP *call_op)
00244 {
00245 OP *jump_op;
00246 TOP jump_top;
00247 TOP call_top = OP_code(call_op);
00248 switch (call_top) {
00249 case TOP_br_r_call:
00250 jump_top = TOP_br_r_cond;
00251 break;
00252 case TOP_br_call:
00253 jump_top = TOP_br_cond;
00254 break;
00255 default:
00256 FmtAssert(FALSE, ("don't know how to generate tail call for %s",
00257 TOP_Name(call_top)));
00258
00259 }
00260
00261 Is_True(OP_opnds(call_op) == 6, ("unexpected number of call opnds"));
00262 jump_op = Mk_OP(jump_top, OP_opnd(call_op, 0),
00263 OP_opnd(call_op, 1),
00264 OP_opnd(call_op, 2),
00265 OP_opnd(call_op, 3),
00266 OP_opnd(call_op, 4));
00267 Is_True(OP_opnds(jump_op) == 5, ("unexpected number of jump opnds"));
00268 return jump_op;
00269 }