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
00037
00038
00039
00040
00041
00042 #include "defs.h"
00043 #include "erglob.h"
00044 #include "ercg.h"
00045 #include "tracing.h"
00046 #include "config.h"
00047 #include "config_targ_opt.h"
00048 #include "tn.h"
00049 #include "cg_flags.h"
00050 #include "op.h"
00051 #include "cgexp.h"
00052 #include "cgexp_internals.h"
00053
00054 void
00055 Initialize_Branch_Variants(void)
00056 {
00057
00058 }
00059
00060
00061
00062
00063 TOP
00064 Pick_Compare_TOP (VARIANT *variant, TN **src1, TN **src2, OPS *ops)
00065 {
00066 TOP cmp = TOP_UNDEFINED;
00067 TOP cmp_i = TOP_UNDEFINED;
00068 INT64 val;
00069
00070 if (*src1 != NULL && TN_has_value(*src1)) {
00071
00072 TN *tmp = *src1;
00073 *src1 = *src2;
00074 *src2 = tmp;
00075 *variant = Invert_BR_Variant(*variant);
00076 }
00077
00078 if (*src2 != NULL && TN_is_zero(*src2)) {
00079 switch (*variant) {
00080 case V_BR_U8LT:
00081 case V_BR_U4LT:
00082 *variant = V_BR_NEVER; break;
00083 case V_BR_U8GE:
00084 case V_BR_U4GE:
00085 *variant = V_BR_ALWAYS; break;
00086
00087 case V_BR_U4LE:
00088 *variant = V_BR_U4EQ; break;
00089
00090 case V_BR_U8LE:
00091 *variant = V_BR_U8EQ; break;
00092 }
00093 }
00094
00095
00096 switch (*variant) {
00097 case V_BR_I8EQ:
00098 case V_BR_U8EQ:
00099 case V_BR_I8NE:
00100 case V_BR_U8NE:
00101 case V_BR_I4EQ:
00102 case V_BR_U4EQ:
00103 case V_BR_I4NE:
00104 case V_BR_U4NE:
00105 break;
00106
00107 case V_BR_I8LT:
00108 case V_BR_I4LT:
00109 cmp_i = TOP_slti; cmp = TOP_slt;
00110 break;
00111 case V_BR_U8LT:
00112 case V_BR_U4LT:
00113 cmp_i = TOP_sltiu; cmp = TOP_sltu;
00114 break;
00115
00116 case V_BR_I8GE:
00117 case V_BR_I4GE:
00118 cmp_i = TOP_slti; cmp = TOP_slt;
00119 break;
00120 case V_BR_U8GE:
00121 case V_BR_U4GE:
00122 cmp_i = TOP_sltiu; cmp = TOP_sltu;
00123 break;
00124
00125 case V_BR_I8GT:
00126 case V_BR_I4GT:
00127 if (TN_has_value(*src2)) {
00128 val = TN_value(*src2);
00129 *src2 = Gen_Literal_TN(val+1, TN_size(*src2));
00130 cmp_i = TOP_slti; cmp = TOP_slt;
00131 *variant = (*variant == V_BR_I8GT) ? V_BR_I8GE : V_BR_I4GE;
00132 }
00133 else {
00134 TN *tmp = *src1;
00135 *src1 = *src2;
00136 *src2 = tmp;
00137 *variant = Invert_BR_Variant(*variant);
00138 cmp_i = TOP_slti; cmp = TOP_slt;
00139 }
00140 break;
00141 case V_BR_U8GT:
00142 case V_BR_U4GT:
00143 if (TN_has_value(*src2)) {
00144 val = TN_value(*src2);
00145 if (val == -1) {
00146 *variant = V_BR_NEVER;
00147 break;
00148 }
00149 *src2 = Gen_Literal_TN(val+1, TN_size(*src2));
00150 cmp_i = TOP_sltiu; cmp = TOP_sltu;
00151 *variant = (*variant == V_BR_U8GT) ? V_BR_U8GE : V_BR_U4GE;
00152 }
00153 else {
00154 TN *tmp = *src1;
00155 *src1 = *src2;
00156 *src2 = tmp;
00157 *variant = Invert_BR_Variant(*variant);
00158 cmp_i = TOP_sltiu; cmp = TOP_sltu;
00159 }
00160 break;
00161
00162 case V_BR_I8LE:
00163 case V_BR_I4LE:
00164 if (TN_has_value(*src2)) {
00165 val = TN_value(*src2);
00166 *src2 = Gen_Literal_TN(val+1, TN_size(*src2));
00167 cmp_i = TOP_slti; cmp = TOP_slt;
00168 *variant = (*variant == V_BR_I8LE) ? V_BR_I8LT : V_BR_I4LT;
00169 }
00170 else {
00171 TN *tmp = *src1;
00172 *src1 = *src2;
00173 *src2 = tmp;
00174 *variant = Invert_BR_Variant(*variant);
00175 cmp_i = TOP_slti; cmp = TOP_slt;
00176 }
00177 break;
00178 case V_BR_U8LE:
00179 case V_BR_U4LE:
00180 if (TN_has_value(*src2)) {
00181 val = TN_value(*src2);
00182 if (val == -1) {
00183 *variant = V_BR_ALWAYS;
00184 break;
00185 }
00186 *src2 = Gen_Literal_TN(val+1, TN_size(*src2));
00187 cmp_i = TOP_sltiu; cmp = TOP_sltu;
00188 *variant = (*variant == V_BR_U8LE) ? V_BR_U8LT : V_BR_U4LT;
00189 }
00190 else {
00191 TN *tmp = *src1;
00192 *src1 = *src2;
00193 *src2 = tmp;
00194 *variant = Invert_BR_Variant(*variant);
00195 cmp_i = TOP_sltiu; cmp = TOP_sltu;
00196 }
00197 break;
00198
00199 case V_BR_FEQ: cmp = TOP_c_eq_s; break;
00200 case V_BR_DEQ: cmp = TOP_c_eq_d; break;
00201 #if defined(TARG_SL)
00202 case V_BR_FLT: cmp = TOP_c_olt_s; break;
00203 #else
00204 case V_BR_FLT: cmp = TOP_c_lt_s; break;
00205 #endif
00206 case V_BR_DLT: cmp = TOP_c_lt_d; break;
00207 #if defined(TARG_SL)
00208 case V_BR_FLE: cmp = TOP_c_ole_s; break;
00209 #else
00210 case V_BR_FLE: cmp = TOP_c_le_s; break;
00211 #endif
00212 case V_BR_DLE: cmp = TOP_c_le_d; break;
00213 case V_BR_FNE: cmp = TOP_c_neq_s; break;
00214 case V_BR_DNE: cmp = TOP_c_neq_d; break;
00215 case V_BR_FGT:
00216 {
00217 TN *tmp = *src1;
00218 *src1 = *src2;
00219 *src2 = tmp;
00220 *variant = Invert_BR_Variant(*variant);
00221 #if defined(TARG_SL)
00222 cmp = TOP_c_olt_s;
00223 #else
00224 cmp = TOP_c_lt_s;
00225 #endif
00226 break;
00227 }
00228 case V_BR_DGT:
00229 {
00230 TN *tmp = *src1;
00231 *src1 = *src2;
00232 *src2 = tmp;
00233 *variant = Invert_BR_Variant(*variant);
00234 cmp = TOP_c_lt_d;
00235 break;
00236 }
00237 case V_BR_FGE:
00238 {
00239 TN *tmp = *src1;
00240 *src1 = *src2;
00241 *src2 = tmp;
00242 *variant = Invert_BR_Variant(*variant);
00243 #if defined(TARG_SL)
00244 cmp = TOP_c_ole_s; break;
00245 #else
00246 cmp = TOP_c_le_s; break;
00247 #endif
00248 }
00249 case V_BR_DGE:
00250 {
00251 TN *tmp = *src1;
00252 *src1 = *src2;
00253 *src2 = tmp;
00254 *variant = Invert_BR_Variant(*variant);
00255 cmp = TOP_c_le_d; break;
00256 }
00257 default: ;
00258 }
00259
00260
00261
00262
00263 if (*src2 == NULL)
00264 return TOP_UNDEFINED;
00265
00266
00267 if (TN_has_value(*src2)) {
00268 if (cmp_i != TOP_UNDEFINED &&
00269 ISA_LC_Value_In_Class(TN_value(*src2), LC_simm16))
00270 cmp = cmp_i;
00271 else
00272 *src2 = Expand_Immediate_Into_Register(*src2, TN_size(*src1) == 8, ops);
00273 }
00274
00275 return cmp;
00276 }
00277
00278 void
00279 Expand_Branch ( TN *targ, TN *src1, TN *src2, VARIANT variant, OPS *ops)
00280 {
00281 TOP cmp;
00282 BOOL false_br = V_false_br(variant);
00283 VARIANT cond = V_br_condition(variant);
00284
00285
00286 if ( Trace_Exp2 ) {
00287 fprintf ( TFile, "<cgexp> Translating %s branch:\n",
00288 (false_br ? "false" : "true") );
00289 }
00290
00291 FmtAssert( cond <= V_BR_LAST, ("unexpected variant in Expand_Branch"));
00292 FmtAssert( cond != V_BR_NONE, ("BR_NONE variant in Expand_Branch"));
00293
00294 cmp = Pick_Compare_TOP (&cond, &src1, &src2, ops);
00295
00296 if ( Trace_Exp2 && cond != variant) {
00297 fprintf ( TFile, "<cgexp> transformed branch cond = %lld\n", cond);
00298 }
00299
00300 switch (cond) {
00301 case V_BR_ALWAYS:
00302 case V_BR_NEVER:
00303 Is_True(cmp == TOP_UNDEFINED,
00304 ("unexpected compare op for %s", BR_Variant_Name(cond)));
00305 if ((cond == V_BR_ALWAYS) ^ false_br) {
00306
00307 Build_OP (TOP_j, targ, ops);
00308 }
00309 break;
00310 case V_BR_PEQ:
00311 case V_BR_PNE:
00312 case V_BR_P_TRUE:
00313 FmtAssert(FALSE, ("unimplemented branch variant in Expand_Branch"));
00314 break;
00315 default:
00316 {
00317 TOP top;
00318
00319 TN *tmp;
00320 if (cmp != TOP_UNDEFINED) {
00321 if (TOP_is_flop(cmp)) {
00322 TN *fcc_tmp = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 1);
00323
00324 if (cmp == TOP_c_neq_s || cmp == TOP_c_neq_d) {
00325 if(Target_ISA<TARGET_ISA_M4){
00326 Build_OP ((cmp == TOP_c_neq_d)?TOP_c_eq_d:TOP_c_eq_s,
00327 src1, src2, ops);
00328 Build_OP (false_br?TOP_bc1t:TOP_bc1f, targ, ops);
00329 }
00330 else{
00331 Build_OP ((cmp == TOP_c_neq_d)?TOP_c_eq_d:TOP_c_eq_s,
00332 fcc_tmp, src1, src2, ops);
00333 Build_OP (false_br?TOP_bc1t:TOP_bc1f, fcc_tmp, targ, ops);
00334 }
00335 } else {
00336 Build_OP (cmp, fcc_tmp, src1, src2, ops);
00337 Build_OP (false_br?TOP_bc1f:TOP_bc1t, fcc_tmp, targ, ops);
00338 }
00339 }
00340 else {
00341 if (TN_is_constant(src2) &&
00342 TN_has_value(src2) &&
00343 (TN_value(src2) == 0)) {
00344 if (cond == V_BR_I8LT || cond == V_BR_U8LT ||
00345 cond == V_BR_I4LT || cond == V_BR_U4LT)
00346 top = TOP_bltz;
00347 else top = TOP_bgez;
00348 Build_OP (top, src1, targ, ops);
00349 } else {
00350 tmp = Build_TN_Of_Mtype (MTYPE_I4);
00351 Build_OP (cmp, tmp, src1, src2, ops);
00352 if (cond == V_BR_I8LT || cond == V_BR_U8LT ||
00353 cond == V_BR_I4LT || cond == V_BR_U4LT)
00354 top = TOP_bne;
00355 else top = TOP_beq;
00356 Build_OP (top, tmp, Zero_TN, targ, ops);
00357 }
00358 }
00359 }
00360 else {
00361 switch (cond) {
00362 case V_BR_I8GE: top = TOP_bgez; break;
00363 case V_BR_I8GT: top = TOP_bgtz; break;
00364 case V_BR_I8LE: top = TOP_blez; break;
00365 case V_BR_I8LT: top = TOP_bltz; break;
00366 case V_BR_I8EQ: top = TOP_beq; break;
00367 case V_BR_U8EQ: top = TOP_beq; break;
00368 case V_BR_I8NE: top = TOP_bne; break;
00369 case V_BR_U8NE: top = TOP_bne; break;
00370 case V_BR_I4GE: top = TOP_bgez; break;
00371 case V_BR_I4GT: top = TOP_bgtz; break;
00372 case V_BR_I4LE: top = TOP_blez; break;
00373 case V_BR_I4LT: top = TOP_bltz; break;
00374 case V_BR_I4EQ: top = TOP_beq; break;
00375 case V_BR_U4EQ: top = TOP_beq; break;
00376 case V_BR_I4NE: top = TOP_bne; break;
00377 case V_BR_U4NE: top = TOP_bne; break;
00378 default:
00379 FmtAssert(FALSE, ("unimplemented branch variant in Expand_Branch"));
00380 }
00381 if (top == TOP_bne || top == TOP_beq)
00382 Build_OP(top, src1, TN_is_zero(src2) ? Zero_TN : src2, targ, ops);
00383 else Build_OP(top, src1, targ, ops);
00384 }
00385 }
00386 break;
00387 }
00388 }
00389
00390 void Exp_Indirect_Branch (TN *targ_reg, OPS *ops)
00391 {
00392 #if defined(TARG_SL)
00393 Build_OP(TOP_mvtc, JA_TN, targ_reg, ops);
00394 Build_OP(TOP_jr, JA_TN, ops);
00395 #else
00396 Build_OP(TOP_jr, targ_reg, ops);
00397 #endif
00398 }
00399
00400 #if defined(TARG_SL) && defined(TARG_SL2)
00401 void Exp_Local_Jump(BB * bb, INT64 offset, OPS * ops)
00402 {
00403 if(Gen_PIC_Shared) {
00404 ST *st = Gen_ST_For_BB(bb);
00405 TN *tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, Pointer_Size);
00406 Exp_Lda(MTYPE_U4, tn, st, offset, OPERATOR_UNKNOWN, ops);
00407 Build_OP(TOP_jr, tn, ops);
00408 } else {
00409
00410
00411 LABEL_IDX lab = Gen_Label_For_BB(bb);
00412 TN *lab_tn = Gen_Label_TN(lab, offset);
00413 Build_OP(TOP_j, lab_tn, ops);
00414 }
00415
00416 }
00417 #else
00418 void Exp_Local_Jump(BB *bb, INT64 offset, OPS *ops)
00419 {
00420 FmtAssert(FALSE, ("NYI: Exp_Local_Jump"));
00421 }
00422 #endif
00423
00424 void Exp_Return (TN *return_address, OPS *ops)
00425 {
00426 #if defined(TARG_SL)
00427 Build_OP(TOP_ret,return_address, ops);
00428 #else
00429 Build_OP(TOP_jr, return_address, ops);
00430 #endif
00431 }
00432
00433 void Exp_Call (OPERATOR opr, TN *return_address, TN *target, OPS *ops)
00434 {
00435 TOP top;
00436 switch (opr) {
00437 case OPR_CALL:
00438 top = TOP_jal;
00439 break;
00440 case OPR_ICALL:
00441 #if 0
00442 if ( ! Get_Trace (TP_CGEXP, 256)) {
00443
00444 OPCODE opc = OPCODE_make_op (OPR_LDID, Pointer_Mtype, Pointer_Mtype);
00445 TN *tmp1 = Build_TN_Of_Mtype (Pointer_Mtype);
00446 Expand_Load (opc, GP_TN, target, Gen_Literal_TN(8, 4), V_NONE, ops);
00447 Expand_Load (opc, tmp1, target, Gen_Literal_TN(0, 4), V_NONE, ops);
00448 target = tmp1;
00449 }
00450 #endif
00451
00452 case OPR_PICCALL:
00453 top = TOP_jalr;
00454 #if defined(TARG_SL)
00455 Build_OP(TOP_mvtc, JA_TN, target, ops);
00456 Build_OP (top, return_address, JA_TN, ops);
00457 return;
00458 #endif
00459 break;
00460 default:
00461 FmtAssert(FALSE, ("unexpected opr in Exp_Call"));
00462
00463 }
00464 Build_OP (top, return_address, target, ops);
00465 }