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
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #define __STDC_LIMIT_MACROS
00063 #include <stdint.h>
00064 #include "defs.h"
00065 #include "config.h"
00066 #include "erglob.h"
00067 #include "ercg.h"
00068 #include "glob.h"
00069 #include "tracing.h"
00070 #include "util.h"
00071
00072 #include "tn.h"
00073 #include "cg_flags.h"
00074 #include "bb.h"
00075 #include "symtab.h"
00076 #include "opcode.h"
00077 #include "const.h"
00078 #include "targ_const.h"
00079 #include "op.h"
00080 #include "data_layout.h"
00081 #include "stblock.h"
00082 #include "cgexp.h"
00083 #include "cgexp_internals.h"
00084 #include "w2op.h"
00085 #include "label_util.h"
00086 #include "cgtarget.h"
00087 #include "whirl2ops.h"
00088 #include "targ_sim.h"
00089 #ifdef TARG_SL
00090 #include "exp_intrn_info.h"
00091 #include "exp_slintrn.h"
00092 #include "printsrc.h"
00093 extern void Set_OP_To_WN_Map(WN *wn);
00094 #endif
00095
00096
00097 #include <iostream>
00098 #include <vector>
00099 #include <stdlib.h>
00100 #include <strings.h>
00101 #include <map>
00102 #include <fstream>
00103 #include <string>
00104 #include <ctype.h>
00105 #include "glob.h"
00106 #include "lib_phase_dir.h"
00107
00108 BOOL Reuse_Temp_TNs = FALSE;
00109
00110 BOOL Trace_Exp2 = FALSE;
00111
00112
00113 static BOOL Disable_Const_Mult_Opt = FALSE;
00114
00115
00116
00117
00118
00119
00120
00121
00122 #define DUP_TN(tn) Dup_TN_Even_If_Dedicated(tn)
00123
00124 static TN_MAP _TN_Pair_table = NULL;
00125
00126 void Init_TN_Pair()
00127 {
00128 }
00129
00130 void
00131 Expand_Start()
00132 {
00133 FmtAssert(_TN_Pair_table == NULL, ("Expand_Start: TN_Pair_table is not NULL"));
00134 _TN_Pair_table = TN_MAP_Create();
00135 }
00136
00137 void
00138 Expand_Finish()
00139 {
00140 FmtAssert(_TN_Pair_table != NULL, ("Expand_Finish: TN_Pair_table is NULL"));
00141 TN_MAP_Delete(_TN_Pair_table);
00142 _TN_Pair_table = NULL;
00143 }
00144
00145
00146 TN *
00147 Get_TN_Pair(TN *key)
00148 {
00149 TN *pair = NULL;
00150
00151 if (TN_is_register(key)) {
00152 pair = (TN *)TN_MAP_Get(_TN_Pair_table, key);
00153 }
00154
00155 return pair;
00156 }
00157
00158 void
00159 Create_TN_Pair(TN *key, TN *pair)
00160 {
00161 FmtAssert(Get_TN_Pair(key) == NULL, ("Create_TN_Pair: TN pair has been set up"));
00162 TN_MAP_Set(_TN_Pair_table, key, pair);
00163 }
00164
00165 void
00166 Add_TN_Pair(TN *key, TN *pair)
00167 {
00168 Create_TN_Pair(key, pair);
00169 }
00170
00171 TN *
00172 Reset_TN_Pair(TN *key)
00173 {
00174 TN *pair = Get_TN_Pair(key);
00175 TN_MAP_Set(_TN_Pair_table, key, NULL);
00176 return pair;
00177 }
00178
00179
00180
00181
00182 TN *
00183 Create_TN_Pair(TN *key, TYPE_ID mtype)
00184 {
00185 FmtAssert(TN_is_register(key), ("NYI"));
00186
00187 if (mtype == MTYPE_I8)
00188 mtype = MTYPE_I4;
00189 else if (mtype == MTYPE_U8)
00190 mtype = MTYPE_U4;
00191 else
00192 FmtAssert(FALSE, ("Create_TN_Pair: invalid mtype %d\n", mtype));
00193
00194 TN *pair = Get_TN_Pair(key);
00195
00196 if (pair == NULL) {
00197 Set_TN_size(key, MTYPE_byte_size(mtype));
00198
00199
00200
00201 pair = Build_TN_Like(key);
00202 TN_MAP_Set(_TN_Pair_table, key, pair);
00203 }
00204
00205 if (TN_register(key) != REGISTER_UNDEFINED) {
00206
00207 }
00208
00209 return pair;
00210 }
00211
00212 TN *
00213 Get_64Bit_High_TN(TN *low, TYPE_ID type, OPS * ops)
00214 {
00215 TYPE_ID mt_high = MTYPE_is_signed(type) ? MTYPE_I4 : MTYPE_U4;
00216 TN *tn_high = Get_TN_Pair(low);
00217
00218 if (tn_high == NULL)
00219 tn_high = Build_TN_Of_Mtype(mt_high);
00220
00221 if (mt_high == MTYPE_U4) {
00222 Build_OP(TOP_or, tn_high, Zero_TN, Zero_TN, ops);
00223 } else {
00224 Build_OP(TOP_sra, tn_high, low, Gen_Literal_TN(31, 4), ops);
00225 }
00226
00227 return tn_high;
00228 }
00229
00230 INT64
00231 Get_TN_Value(TN *tn)
00232 {
00233 FmtAssert(TN_is_constant(tn), ("Get_TN_Value: TN is not a const tn\n"));
00234
00235 INT64 val;
00236 if (TN_has_value(tn)) {
00237 val = TN_value(tn);
00238 } else if (TN_is_symbol(tn)) {
00239 ST *base;
00240 INT64 val;
00241 Base_Symbol_And_Offset_For_Addressing(TN_var(tn), TN_offset(tn), &base, &val);
00242 } else {
00243 FmtAssert(FALSE, ("Get_TN_Value: Unexpected constant\n"));
00244 }
00245
00246 return val;
00247 }
00248
00249 void
00250 Expand_TN_Pair(TN ** low, TN ** high, TYPE_ID mtype, OPS *ops)
00251 {
00252 *high = Get_TN_Pair(*low);
00253
00254 if (TN_is_constant(*low)) {
00255 if (TN_has_value(*low)) {
00256 *low = Expand_Immediate_Into_Register(*low, TRUE, ops);
00257 *high = Get_TN_Pair(*low);
00258 }
00259 else {
00260 FmtAssert(FALSE, ("Expand_TN_Pair: Unexpected constant"));
00261 }
00262 }
00263 else if (TN_is_register(*low) && (*high == NULL)){
00264 *high = Get_64Bit_High_TN(*low, mtype, ops);
00265 }
00266
00267 FmtAssert(*high, ("Expand_TN_Pair: high tn get failed"));
00268 }
00269
00270 static void Expand_32Bit_Int_Less(TN *, TN *, TN *, TYPE_ID, OPS *);
00271 static void Expand_32Bit_Int_Less_Equal(TN *, TN *, TN *, TYPE_ID, OPS *);
00272 static void Expand_32Bit_Int_Equal(TN *, TN *, TN *, TYPE_ID, OPS *);
00273 static void Expand_32Bit_Int_Not_Equal(TN *, TN *, TN *, TYPE_ID, OPS *);
00274 static void Expand_32Bit_Int_Greater(TN *, TN *, TN *, TYPE_ID, OPS *);
00275 static void Expand_32Bit_Int_Greater_Equal(TN *, TN *, TN *, TYPE_ID, OPS *);
00276
00277 static void
00278 Expand_64Bit_ALU_OP(OPERATOR opr, TYPE_ID mtype,
00279 TN *result_low, TN *src1_low, TN *src2_low, OPS * ops)
00280 {
00281 TN *result_high = Get_TN_Pair(result_low);
00282 FmtAssert(result_high != NULL, ("Expand_64Bit_ALU_OP: Result tn pair not setup"));
00283
00284 TYPE_ID mt_high = (mtype == MTYPE_U8) ? MTYPE_U4 : MTYPE_I4;
00285
00286 TN *src1_high, *src2_high;
00287 Expand_TN_Pair (&src1_low, &src1_high, mtype, ops);
00288 Expand_TN_Pair (&src2_low, &src2_high, mtype, ops);
00289
00290 switch (opr) {
00291
00292 case OPR_ADD:
00293 {
00294
00295 Expand_Add(result_low, src1_low, src2_low, MTYPE_U4, ops);
00296 Expand_Add(result_high, src1_high, src2_high, mt_high, ops);
00297
00298 TN *carry = Build_TN_Of_Mtype(MTYPE_U4);
00299
00300 if (result_low == src1_low)
00301 Expand_32Bit_Int_Less(carry, result_low, src2_low, MTYPE_U4, ops);
00302 else
00303 Expand_32Bit_Int_Less(carry, result_low, src1_low, MTYPE_U4, ops);
00304
00305 Build_OP((mt_high == MTYPE_U4) ? TOP_addu : TOP_add, result_high, result_high, carry, ops);
00306 break;
00307
00308 }
00309 case OPR_SUB:
00310 {
00311
00312 Expand_Sub(result_low, src1_low, src2_low, MTYPE_U4, ops);
00313 Expand_Sub(result_high, src1_high, src2_high, mt_high, ops);
00314
00315 TN *carry = Build_TN_Of_Mtype(MTYPE_U4);
00316 Expand_32Bit_Int_Less(carry, src1_low, src2_low, MTYPE_U4, ops);
00317
00318 Build_OP(TOP_sub, result_high, result_high, carry, ops);
00319 break;
00320
00321 }
00322 case OPR_MPY:
00323 {
00324
00325 TN *zero_tn = Gen_Literal_TN(0, 4);
00326 TN *carry_low_low = Build_TN_Of_Mtype(MTYPE_U4);
00327 TN *carry_low_high = Build_TN_Of_Mtype(mt_high);
00328
00329
00330 Build_OP(TOP_c3_mulus, HI_TN, result_low, src1_low, src2_low, zero_tn, ops);
00331 Build_OP(TOP_c3_mvfs, carry_low_low, HI_TN, zero_tn, ops);
00332
00333 TOP top = MTYPE_signed(mtype) ? TOP_c3_muls : TOP_c3_mulus;
00334 Build_OP(top, HI_TN, carry_low_high, src1_low, src2_high, zero_tn, ops);
00335 Build_OP(top, HI_TN, result_high, src1_high, src2_low, zero_tn, ops);
00336
00337 Build_OP(TOP_add, result_high, result_high, carry_low_low, ops);
00338 Build_OP(TOP_add, result_high, result_high, carry_low_high, ops);
00339 break;
00340
00341 }
00342
00343 default:
00344 FmtAssert(FALSE, ("Expand_64Bit_ALU_OP: Unexpected Operator"));
00345 }
00346 }
00347
00348 void
00349 Expand_64Bit_Unary_OP(OPERATOR opr, TYPE_ID mtype,
00350 TN *result_low, TN *src_low, OPS* ops)
00351 {
00352 TN *result_high = Get_TN_Pair(result_low);
00353 FmtAssert(result_high != NULL, ("Expand_64Bit_Unary_OP: result tn pair not setup"));
00354
00355 TN *src_high;
00356 Expand_TN_Pair(&src_low, &src_high, mtype, ops);
00357
00358 switch (opr) {
00359 case OPR_NEG:
00360 Expand_64Bit_ALU_OP(OPR_SUB, mtype, result_low, Gen_Literal_TN(0, 4), src_low, ops);
00361 break;
00362 case OPR_BNOT:
00363 Build_OP(TOP_nor, result_low, src_low, src_low, ops);
00364 Build_OP(TOP_nor, result_high, src_high, src_high, ops);
00365 break;
00366 default:
00367 FmtAssert(FALSE, ("Expand_64Bit_Unary_OP: Unexpected operator"));
00368 }
00369 }
00370
00371 static void
00372 Expand_64Bit_BitLogic_OP(OPERATOR opr, TYPE_ID mtype, TN *result_low,
00373 TN *src1_low, TN *src2_low, OPS * ops)
00374 {
00375
00376 TN *result_high = Get_TN_Pair(result_low);
00377 FmtAssert(result_high != NULL, ("Expand_64Bit_Binary_OP: result tn pair not setup"));
00378
00379 TN *src1_high, *src2_high;
00380 Expand_TN_Pair (&src1_low, &src1_high, mtype, ops);
00381 Expand_TN_Pair (&src2_low, &src2_high, mtype, ops);
00382
00383 TYPE_ID mt_high = ((mtype == MTYPE_U8) ? MTYPE_U4 : MTYPE_I4);
00384
00385 typedef void (*Expand_BitLogic_OP_ptr)(TN *, TN *, TN *, TYPE_ID, OPS*);
00386 Expand_BitLogic_OP_ptr Expand_BitLogic_OP;
00387
00388 switch(opr)
00389 {
00390 case OPR_BAND:
00391 Expand_BitLogic_OP = Expand_Binary_And; break;
00392 case OPR_BIOR:
00393 Expand_BitLogic_OP = Expand_Binary_Or; break;
00394 case OPR_BXOR:
00395 Expand_BitLogic_OP = Expand_Binary_Xor; break;
00396 case OPR_BNOR:
00397 FmtAssert(FALSE, ("Expand_64Bit_Binary_OP: Not implement BNOR"));
00398 default:
00399 FmtAssert(FALSE, ("Expand_64Bit_Binary_OP: Unexpected operator"));
00400 }
00401
00402 Expand_BitLogic_OP(result_low, src1_low, src2_low, MTYPE_U4, ops);
00403 Expand_BitLogic_OP(result_high, src1_high, src2_high, mt_high, ops);
00404 }
00405
00406 void
00407 Expand_64Bit_Shift(SHIFT_DIRECTION shift_dir,
00408 TN *result_low, TN *src_low, TN *shift, TYPE_ID mtype, OPS* ops)
00409 {
00410
00411 TN *result_high = Get_TN_Pair(result_low);
00412 FmtAssert(result_high, ("Expand_64Bit_Shift: result TN pair not setup"));
00413
00414 TN *src_high;
00415 Expand_TN_Pair(&src_low, &src_high, mtype, ops);
00416
00417 FmtAssert(result_high && src_high && src_low,
00418 ("Expand_64Bit_Shift: result or operand1 TN pair not setup"));
00419 FmtAssert(TN_has_value(shift), ("Expand_64Bit_Shift : should be a value tn"));
00420
00421 INT64 shift_amt = TN_value(shift);
00422 shift_amt = shift_amt & 0x3f;
00423
00424 if (shift_amt < 0) shift_amt += 64;
00425
00426 if (shift_amt > 32) {
00427 switch (shift_dir) {
00428 case shift_left:
00429 Build_OP(TOP_sll, result_high, src_low, Gen_Literal_TN(shift_amt-32,4), ops);
00430 Build_OP(TOP_or, result_low, Zero_TN, Zero_TN, ops);
00431 break;
00432
00433 case shift_aright:
00434 Build_OP(TOP_sra, result_low, src_high, Gen_Literal_TN(shift_amt-32, 4), ops);
00435 Build_OP(TOP_sra, result_high, src_high, Gen_Literal_TN(31, 4), ops);
00436 break;
00437
00438 case shift_lright:
00439 Build_OP(TOP_srl, result_low, src_high, Gen_Literal_TN(shift_amt-32,4), ops);
00440 Build_OP(TOP_or, result_high, Zero_TN, Zero_TN, ops);
00441 break;
00442 }
00443 } else if (shift_amt == 32) {
00444 switch (shift_dir) {
00445 case shift_left:
00446 Exp_COPY(result_high, src_low, ops);
00447 Build_OP(TOP_or, result_low, Zero_TN, Zero_TN, ops);
00448 break;
00449
00450 case shift_aright:
00451 Exp_COPY(result_low, src_high, ops);
00452 Build_OP(TOP_sra, result_high, src_high, Gen_Literal_TN(31, 4), ops);
00453 break;
00454
00455 case shift_lright:
00456 Exp_COPY(result_low, src_high, ops);
00457 Build_OP(TOP_or, result_high, Zero_TN, Zero_TN, ops);
00458 break;
00459 }
00460 } else if (shift_amt == 0) {
00461 Exp_COPY(result_low, src_low, ops);
00462 Exp_COPY(result_high, src_high, ops);
00463 } else {
00464 TN *tn = Build_TN_Like(result_low);
00465 TN *tn1 = Build_TN_Like(result_high);
00466 switch (shift_dir) {
00467 case shift_left:
00468 Build_OP(TOP_srl, tn, src_low, Gen_Literal_TN(32-shift_amt, 4), ops);
00469 Build_OP(TOP_sll, tn1, src_high, Gen_Literal_TN(shift_amt, 4), ops);
00470 Build_OP(TOP_or, result_high, tn1, tn, ops);
00471 Build_OP(TOP_sll, result_low, src_low, Gen_Literal_TN(shift_amt, 4), ops);
00472 break;
00473
00474 case shift_aright:
00475 Build_OP(TOP_srl, tn, src_low, Gen_Literal_TN(shift_amt, 4), ops);
00476 Build_OP(TOP_sll, tn1, src_high, Gen_Literal_TN(32-shift_amt, 4), ops);
00477 Build_OP(TOP_or, result_low, tn, tn1, ops);
00478 Build_OP(TOP_sra, result_high, src_high, Gen_Literal_TN(shift_amt, 4), ops);
00479 break;
00480
00481 case shift_lright:
00482 Build_OP(TOP_srl, tn, src_low, Gen_Literal_TN(shift_amt, 4), ops);
00483 Build_OP(TOP_sll, tn1, src_high, Gen_Literal_TN(32-shift_amt, 4), ops);
00484 Build_OP(TOP_or, result_low, tn, tn1, ops);
00485 Build_OP(TOP_srl, result_high, src_high, Gen_Literal_TN(shift_amt, 4), ops);
00486 break;
00487 }
00488 }
00489 }
00490
00491
00492 static void
00493 Expand_64Bit_Compare(OPERATOR opr, TN *result, TN *src1_low, TN *src2_low, TYPE_ID mtype, OPS *ops)
00494 {
00495
00496 TYPE_ID mt_high = (mtype == MTYPE_U8) ? MTYPE_U4 : MTYPE_I4;
00497
00498 TN *src1_high, *src2_high;
00499 Expand_TN_Pair(&src1_low, &src1_high, mtype, ops);
00500 Expand_TN_Pair(&src2_low, &src2_high, mtype, ops);
00501
00502 TN *high_cmp1 = Build_TN_Of_Mtype(MTYPE_U4);
00503 TN *high_cmp2 = Build_TN_Of_Mtype(MTYPE_U4);
00504 TN *low_cmp = Build_TN_Of_Mtype(MTYPE_U4);
00505 TN *mid = Build_TN_Of_Mtype(MTYPE_U4);
00506 switch(opr) {
00507 case OPR_EQ:
00508 {
00509 Expand_32Bit_Int_Equal(high_cmp1, src1_high, src2_high, mt_high, ops);
00510 Expand_32Bit_Int_Equal(low_cmp, src1_low, src2_low, MTYPE_U4, ops);
00511
00512 Build_OP(TOP_and, result, high_cmp1, low_cmp, ops);
00513 break;
00514 }
00515 case OPR_NE:
00516 {
00517 Expand_32Bit_Int_Equal(high_cmp1, src1_high, src2_high, mt_high, ops);
00518 Expand_32Bit_Int_Not_Equal(low_cmp, src1_low, src2_low, MTYPE_U4, ops);
00519 Expand_32Bit_Int_Not_Equal(high_cmp2, src1_high, src2_high, mt_high, ops);
00520
00521 Build_OP(TOP_and, mid, high_cmp1, low_cmp, ops);
00522 Build_OP(TOP_or, result, high_cmp2, mid, ops);
00523 break;
00524 }
00525 case OPR_LT:
00526 {
00527 Expand_32Bit_Int_Equal(high_cmp1, src1_high, src2_high, mt_high, ops);
00528 Expand_32Bit_Int_Less(low_cmp, src1_low, src2_low, MTYPE_U4, ops);
00529 Expand_32Bit_Int_Less(high_cmp2, src1_high, src2_high, mt_high, ops);
00530
00531 Build_OP(TOP_and, mid, high_cmp1, low_cmp, ops);
00532 Build_OP(TOP_or, result, high_cmp2, mid, ops);
00533 break;
00534 }
00535 case OPR_LE:
00536 {
00537 Expand_32Bit_Int_Equal(high_cmp1, src1_high, src2_high, mt_high, ops);
00538 Expand_32Bit_Int_Less_Equal(low_cmp, src1_low, src2_low, MTYPE_U4, ops);
00539 Expand_32Bit_Int_Less(high_cmp2, src1_high, src2_high, mt_high, ops);
00540
00541 Build_OP(TOP_and, mid, high_cmp1, low_cmp, ops);
00542 Build_OP(TOP_or, result, high_cmp2, mid, ops);
00543 break;
00544 }
00545 case OPR_GT:
00546 {
00547 Expand_32Bit_Int_Equal(high_cmp1, src1_high, src2_high, mt_high, ops);
00548 Expand_32Bit_Int_Greater(low_cmp, src1_low, src2_low, MTYPE_U4, ops);
00549 Expand_32Bit_Int_Greater(high_cmp2, src1_high, src2_high, mt_high, ops);
00550
00551 Build_OP(TOP_and, mid, high_cmp1, low_cmp, ops);
00552 Build_OP(TOP_or, result, high_cmp2, mid, ops);
00553 break;
00554 }
00555 case OPR_GE:
00556 {
00557 Expand_32Bit_Int_Equal(high_cmp1, src1_high, src2_high, mt_high, ops);
00558 Expand_32Bit_Int_Greater_Equal(low_cmp, src1_low, src2_low, MTYPE_U4, ops);
00559 Expand_32Bit_Int_Greater(high_cmp2, src1_high, src2_high, mt_high, ops);
00560
00561 Build_OP(TOP_and, mid, high_cmp1, low_cmp, ops);
00562 Build_OP(TOP_or, result, high_cmp2, mid, ops);
00563 break;
00564 }
00565 default:
00566 {
00567 FmtAssert(FALSE, ("Expand_64Bit_Compare: Unexpected compare operator"));
00568 }
00569 }
00570 }
00571
00572 static void
00573 Expand_64Bit_Int_Equal(TN *result, TN *src1_low, TN *src2_low, TYPE_ID mtype, OPS *ops)
00574 {
00575 Expand_64Bit_Compare(OPR_EQ, result, src1_low, src2_low, mtype, ops);
00576 }
00577
00578 static void
00579 Expand_64Bit_Int_Not_Equal(TN *result, TN *src1_low, TN *src2_low, TYPE_ID mtype, OPS *ops)
00580 {
00581 Expand_64Bit_Compare(OPR_NE, result, src1_low, src2_low, mtype, ops);
00582 }
00583
00584 static void
00585 Expand_64Bit_Int_Less (TN *result, TN *src1_low, TN *src2_low, TYPE_ID mtype, OPS *ops)
00586 {
00587 Expand_64Bit_Compare(OPR_LT, result, src1_low, src2_low, mtype, ops);
00588 }
00589
00590 static void
00591 Expand_64Bit_Int_Less_Equal(TN *result, TN *src1_low, TN *src2_low, TYPE_ID mtype, OPS *ops)
00592 {
00593 Expand_64Bit_Compare(OPR_LE, result, src1_low, src2_low, mtype, ops);
00594 }
00595
00596 static void
00597 Expand_64Bit_Int_Greater(TN *result, TN *src1_low, TN *src2_low, TYPE_ID mtype, OPS *ops)
00598 {
00599 Expand_64Bit_Compare(OPR_GT, result, src1_low, src2_low, mtype, ops);
00600 }
00601
00602 static void
00603 Expand_64Bit_Int_Greater_Equal(TN *result, TN *src1_low, TN *src2_low, TYPE_ID mtype, OPS *ops)
00604 {
00605 Expand_64Bit_Compare(OPR_GE, result, src1_low, src2_low, mtype, ops);
00606 }
00607
00608 static void
00609 Expand_64Bit_Abs(TN *result_low, TN *src_low, TYPE_ID mtype, OPS* ops)
00610 {
00611 TN *result_high = Get_TN_Pair(result_low);
00612 FmtAssert(result_high, ("Expand_64Bit_Abs: result tn pair not setup"));
00613
00614 TN *src_high;
00615 Expand_TN_Pair(&src_low, &src_high, mtype, ops);
00616
00617 if (MTYPE_is_unsigned(mtype)) {
00618 Expand_Copy(result_low, src_low, mtype, ops);
00619 return;
00620 }
00621
00622 TN *sign_bit = Build_TN_Of_Mtype(MTYPE_U4);
00623 Build_OP(TOP_srl, sign_bit, src_high, Gen_Literal_TN(31, 4), ops);
00624 Build_OP(TOP_mc_abs, result_high, src_high, ops);
00625 Build_OP(TOP_sub, result_high, result_high, sign_bit, ops);
00626 Build_OP(TOP_mc_zn_eq, result_low, sign_bit, src_low, Gen_Literal_TN(0, 4), ops);
00627 }
00628
00629 static void
00630 Expand_64Bit_Cvtl(TN *result_low, TN *src_low, TN *len,
00631 TYPE_ID mtype, BOOL signed_extension, OPS *ops)
00632 {
00633 TN *result_h = Get_TN_Pair(result_low);
00634 FmtAssert(result_h, ("Expand_64Bit_Abs: result tn pair not setup"));
00635
00636 TN *src_high;
00637 Expand_TN_Pair(&src_low, &src_high, mtype, ops);
00638
00639 TYPE_ID mt = (mtype == MTYPE_I8) ? MTYPE_I4 : MTYPE_U4;
00640
00641 INT64 l = TN_value(len);
00642 if (l <= 32) {
00643 Expand_Convert_Length(result_low, src_low, len, mt, mt, ops);
00644
00645 if (result_h != NULL) {
00646 if (signed_extension) {
00647 Build_OP(TOP_sra, result_h, result_low, Gen_Literal_TN(31, 4), ops);
00648 } else {
00649 Build_OP(TOP_or, result_h, Zero_TN, Zero_TN, ops);
00650 }
00651 }
00652 } else {
00653 FmtAssert(src_high != NULL, ("Expand_64Bit_Cvtl: src_high not setup"));
00654
00655 Expand_Copy(result_low, src_low, MTYPE_I4, ops);
00656 Expand_Convert_Length(result_h, src_high, Gen_Literal_TN(l - 32, 4), mt,
00657 MTYPE_is_signed(mt), ops);
00658 }
00659 }
00660
00661 void
00662 Expand_Copy (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
00663 {
00664 if (MTYPE_is_float(mtype)) {
00665 if (mtype == MTYPE_F8) {
00666 TN *result_pair = Get_TN_Pair(result);
00667 TN *src_pair = Get_TN_Pair(src);
00668
00669 FmtAssert(result_pair != NULL, ("Expand_Copy: double result TN pair not setup"));
00670 FmtAssert(src_pair != NULL, ("Expand_Copy: double source TN pair not setup"));
00671
00672 Build_OP(TOP_or, result, src, Zero_TN, ops);
00673 Set_OP_copy(OPS_last(ops));
00674 Build_OP(TOP_or, result_pair, src_pair, Zero_TN, ops);
00675 Set_OP_copy (OPS_last(ops));
00676 } else if (mtype == MTYPE_F4) {
00677 Build_OP(TOP_or, result, src, Zero_TN, ops);
00678 Set_OP_copy(OPS_last(ops));
00679 } else {
00680 FmtAssert(FALSE, ("Expand_Copy: Unexpected float type"));
00681 }
00682 }
00683 else {
00684 if (MTYPE_is_longlong(mtype)) {
00685 TN *result_pair = Get_TN_Pair(result);
00686 TN *src_pair = Get_TN_Pair(src);
00687
00688 FmtAssert(result_pair != NULL, ("Expand_Copy: result TN pair not setup"));
00689 Build_OP(TOP_or, result, src, Zero_TN, ops);
00690 Set_OP_copy(OPS_last(ops));
00691
00692 if (src_pair != NULL) {
00693 Build_OP(TOP_or, result_pair, src_pair, Zero_TN, ops);
00694 Set_OP_copy (OPS_last(ops));
00695 } else {
00696 result_pair = Get_64Bit_High_TN(result, mtype, ops);
00697 }
00698 } else {
00699 Build_OP(TOP_or, result, src, Zero_TN, ops);
00700 Set_OP_copy(OPS_last(ops));
00701 }
00702 }
00703 Build_OP(TOP_or, result, src, Zero_TN, ops);
00704 Set_OP_copy(OPS_last(ops));
00705 }
00706
00707
00708
00709
00710 void
00711 Expand_Copy_Extension (TN *result, TN *src, TYPE_ID mtype, BOOL signed_extension, OPS *ops)
00712 {
00713 if (MTYPE_is_float(mtype)) {
00714 if (mtype == MTYPE_F8) {
00715 TN *result_pair = Get_TN_Pair(result);
00716 TN *src_pair = Get_TN_Pair(src);
00717
00718 FmtAssert(result_pair != NULL, ("Expand_Copy: double result TN pair not setup"));
00719 FmtAssert(src_pair != NULL, ("Expand_Copy: double source TN pair not setup"));
00720
00721 Build_OP(TOP_or, result, src, Zero_TN, ops);
00722 Set_OP_copy(OPS_last(ops));
00723 Build_OP(TOP_or, result_pair, src_pair, Zero_TN, ops);
00724 Set_OP_copy (OPS_last(ops));
00725 } else if (mtype == MTYPE_F4) {
00726 Build_OP(TOP_or, result, src, Zero_TN, ops);
00727 Set_OP_copy(OPS_last(ops));
00728 } else {
00729 FmtAssert(FALSE, ("Expand_Copy_Extension: Unexpected type"));
00730 }
00731 }
00732 else {
00733 if (MTYPE_is_longlong(mtype)) {
00734 TN *result_pair = Get_TN_Pair(result);
00735 TN *src_pair = Get_TN_Pair(src);
00736
00737 FmtAssert(result_pair != NULL, ("result TN pair not setup"));
00738 Build_OP(TOP_or, result, src, Zero_TN, ops);
00739 Set_OP_copy(OPS_last(ops));
00740
00741 if (src_pair != NULL) {
00742 Build_OP(TOP_or, result_pair, src_pair, Zero_TN, ops);
00743 Set_OP_copy (OPS_last(ops));
00744 } else {
00745 if (!signed_extension)
00746 Build_OP(TOP_or, result_pair, Zero_TN, Zero_TN, ops);
00747 else
00748 Build_OP(TOP_sra, result_pair, result, Gen_Literal_TN(31, 4), ops);
00749 }
00750 } else {
00751 Build_OP(TOP_or, result, src, Zero_TN, ops);
00752 Set_OP_copy(OPS_last(ops));
00753 }
00754 }
00755 }
00756
00757
00758
00759
00760 static void
00761 Fixup_32_Bit_Op(TN *result,TN *src, TYPE_ID dest_type, OPS *ops)
00762 {
00763 if (dest_type == MTYPE_I8 || dest_type == MTYPE_U8) {
00764 Expand_Copy(result,src,dest_type,ops);
00765 } else {
00766 Expand_Convert_Length (result, src, Gen_Literal_TN(MTYPE_size_reg(dest_type), 4),
00767 dest_type, MTYPE_is_signed(dest_type),ops);
00768 }
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 void
00784 Expand_Convert_Length ( TN *dest, TN *src, TN *length_tn, TYPE_ID mtype, BOOL signed_extension, OPS *ops)
00785 {
00786 TN *lit_tn;
00787 FmtAssert (! MTYPE_float(mtype), ("Expand_Convert_Length: illegal data type\n"));
00788 FmtAssert (TN_has_value(length_tn), ("Expand_Convert_Length: non-constant length\n"));
00789 UINT64 val = TN_value(length_tn);
00790
00791 if (MTYPE_is_longlong(mtype)) {
00792 FmtAssert(Get_TN_Pair(dest) != NULL, ("Expand_Convert_Length: result pair not setup"));
00793 Expand_64Bit_Cvtl(dest, src, length_tn, mtype, signed_extension, ops);
00794 } else if (val == 32) {
00795 Build_OP(TOP_or, dest, src, Zero_TN, ops);
00796 } else if (val <= 16 && ! signed_extension) {
00797 Build_OP(TOP_andi, dest, src, Gen_Literal_TN((1 << val) - 1, 4), ops);
00798 } else if (val < 32) {
00799 TN *pos_tn = Gen_Literal_TN(val - 1, 4);
00800 TN *width_tn = Gen_Literal_TN(val, 4);
00801 Build_OP(signed_extension ? TOP_extrbs : TOP_extrbu, dest, src, pos_tn, width_tn, ops);
00802 } else {
00803 FmtAssert(FALSE, ("Unexpected case in Expand_Convert_Length\n"));
00804 }
00805 }
00806
00807 static void
00808 Exp_Immediate_Int (TN *dest, TN *src, TYPE_ID rtype, OPS *ops)
00809 {
00810 INT64 val;
00811 TN *tmp = Build_TN_Like(dest);
00812
00813 if ( TN_has_value(src) ) {
00814 val = TN_value(src);
00815 }
00816 else if ( TN_is_symbol(src) ) {
00817 ST *base;
00818 Base_Symbol_And_Offset_For_Addressing (TN_var(src), TN_offset(src), &base,
00819 &val);
00820 }
00821 else FmtAssert(FALSE,("unexpected constant in Exp_Immediate"));
00822
00823 if (TN_is_symbol(src) && TN_relocs(src) == TN_RELOC_GPSUB) {
00824 Build_OP(TOP_lui, tmp,
00825 Gen_Symbol_TN(TN_var(src), 0, TN_RELOC_HI_GPSUB), ops);
00826 Build_OP(TOP_addiu, dest, tmp, Gen_Symbol_TN(TN_var(src), 0,
00827 TN_RELOC_LO_GPSUB), ops);
00828 }
00829 else if (ISA_LC_Value_In_Class (val, LC_simm16)) {
00830 Build_OP (TOP_addiu, dest, Zero_TN, src, ops);
00831 }
00832 else if (ISA_LC_Value_In_Class (val, LC_uimm16)) {
00833 Build_OP (TOP_ori, dest, Zero_TN, src, ops);
00834 }
00835 else if (val >= INT32_MIN && val <= INT32_MAX){
00836 #if defined(TARG_SL)
00837 if ((val & 0xffff) == 0) {
00838 Build_OP(TOP_lui, dest, Gen_Literal_TN((val >> 16)&0xffff, 4), ops);
00839 } else {
00840 #endif
00841 Build_OP (TOP_lui, tmp, Gen_Literal_TN((val >> 16)&0xffff, 4), ops);
00842 Build_OP (TOP_ori, dest, tmp, Gen_Literal_TN(val & 0xffff, 4), ops);
00843 #if defined(TARG_SL)
00844 }
00845 #endif
00846 }
00847 else if ((UINT64)val <= UINT32_MAX) {
00848 if (TN_size(dest) == 4) {
00849 if ((val & 0xffff) == 0) {
00850 Build_OP (TOP_lui, dest, Gen_Literal_TN((val >> 16) & 0xffff, 4), ops);
00851 } else {
00852 Build_OP (TOP_lui, tmp, Gen_Literal_TN((val >> 16) & 0xffff, 4), ops);
00853 Build_OP (TOP_ori, dest, tmp, Gen_Literal_TN(val & 0xffff, 4), ops);
00854 }
00855 }
00856 else {
00857 Build_OP (TOP_ori, tmp, Zero_TN, Gen_Literal_TN((val >> 16) & 0xffff, 4), ops);
00858 Build_OP (TOP_dsll, tmp, tmp, Gen_Literal_TN(16, 4), ops);
00859 Build_OP (TOP_ori, dest, tmp, Gen_Literal_TN(val & 0xffff, 4), ops);
00860 }
00861 }
00862 else {
00863 TCON tcon = Host_To_Targ (MTYPE_I8, val);
00864 ST *sym = New_Const_Sym (Enter_tcon (tcon), Be_Type_Tbl(MTYPE_I8));
00865 Allocate_Object(sym);
00866 #if 0 // SC temp ifdef out for now to make kvm compile throug
00867 FmtAssert((ST_gprel(sym)), ("sym not gp_rel: handle this"));
00868 #endif
00869 if(ST_gprel(sym)) {
00870
00871 Build_OP(TOP_lw, dest, GP_TN, Gen_Symbol_TN(sym, 0, TN_RELOC_GPREL16), ops);
00872 DevWarn("Long Long value is not supported, constant value has been truncated");
00873 }
00874 else {
00875 Build_OP (TOP_lui, tmp, Gen_Literal_TN((val >> 48) & 0xffff, 8), ops);
00876 Build_OP (TOP_ori, dest, tmp, Gen_Literal_TN((val >> 32) & 0xffff, 8), ops);
00877 DevWarn("Long Long value is not supported, constant value has been truncated");
00878 }
00879 }
00880 }
00881
00882 void
00883 Exp_Immediate (TN *dest, TN *src, TYPE_ID rtype, OPS *ops)
00884 {
00885 Expand_Immediate(dest, src, rtype, ops);
00886 }
00887
00888
00889
00890
00891 void
00892 Expand_Immediate (TN *dest, TN *src, TYPE_ID rtype, OPS *ops)
00893 {
00894 FmtAssert((TN_is_constant(src)),
00895 ("unexpected non-constant in Expand_Immediate"));
00896 FmtAssert((TN_has_value(src) || TN_is_symbol(src)),
00897 ("expected value or const in Expand_Immediate"));
00898
00899 if (MTYPE_is_longlong(rtype) && Get_TN_Pair(dest)){
00900 TN *dest_h = Get_TN_Pair(dest);
00901
00902 INT64 val = TN_value(src);
00903 if (val == 0)
00904 {
00905 Exp_COPY(dest, Zero_TN, ops);
00906 Exp_COPY(dest_h, Zero_TN, ops);
00907 }
00908 else
00909 {
00910 TN *v_l = Gen_Literal_TN((int)(val & 0XFFFFFFFF), 4);
00911 TN *v_h = Gen_Literal_TN((int)(val >> 32), 4);
00912
00913 Expand_Immediate(dest, v_l, MTYPE_I4, ops);
00914 Expand_Immediate(dest_h, v_h, MTYPE_I4, ops);
00915 }
00916 } else {
00917 Exp_Immediate_Int(dest, src, rtype, ops);
00918 }
00919 }
00920
00921 TN *
00922 Expand_Immediate_Into_Register (TN *src, BOOL is_64bit, OPS *ops)
00923 {
00924 if ((TN_value(src) == 0) && (is_64bit == FALSE))
00925 return Zero_TN;
00926
00927
00928 TYPE_ID rtype = is_64bit ? MTYPE_I8 : MTYPE_I4;
00929 TN *tmp;
00930
00931 if (is_64bit == TRUE) {
00932 tmp = Build_TN_Of_Mtype(MTYPE_U4);
00933 Add_TN_Pair(tmp, Build_TN_Of_Mtype(MTYPE_I4));
00934 } else {
00935 tmp = Build_TN_Of_Mtype(MTYPE_I4);
00936 }
00937
00938 Expand_Immediate (tmp, src, rtype, ops);
00939 return tmp;
00940 }
00941
00942 void
00943 Expand_Add (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00944 {
00945 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
00946 ("Expand_Add: illegal result size\n"));
00947 TOP new_opcode;
00948 INT64 val;
00949 BOOL is_64bit = MTYPE_bit_size(mtype) == 64;
00950
00951 if (MTYPE_is_longlong(mtype)) {
00952 FmtAssert(Get_TN_Pair(result), ("Expand_Add: result tn pair not setup"));
00953 Expand_64Bit_ALU_OP(OPR_ADD, mtype, result, src1, src2, ops);
00954 return;
00955 }
00956
00957 if (TN_is_constant(src1)) {
00958 if (TN_has_value(src1)) {
00959 val = TN_value(src1);
00960 if (val == 0) {
00961 Expand_Copy (result, src2, mtype, ops);
00962 return;
00963 }
00964 } else if ( TN_is_symbol(src1) ) {
00965
00966 ST *base;
00967 INT64 val;
00968 TN *tmp = Build_TN_Of_Mtype (mtype);
00969 Base_Symbol_And_Offset_For_Addressing (TN_var(src1), TN_offset(src1),
00970 &base, &val);
00971 new_opcode = is_64bit ? TOP_daddiu : TOP_addiu;
00972 if (ISA_LC_Value_In_Class (val, LC_simm16) ||
00973 ISA_LC_Value_In_Class (val, LC_uimm16)) {
00974 Build_OP (new_opcode, result, src2, src1, ops);
00975 } else if (val >= INT32_MIN && val <= INT32_MAX) {
00976 Build_OP (TOP_lui, tmp, Gen_Literal_TN((val >> 16)&0xffff, 4), ops);
00977 Build_OP (TOP_ori, tmp, tmp, Gen_Literal_TN(val & 0xffff, 4), ops);
00978 Build_OP (is_64bit ? TOP_daddu : TOP_addu, result, tmp, src2, ops);
00979 } else {
00980 TCON tcon = Host_To_Targ (MTYPE_I8, val);
00981 ST *sym = New_Const_Sym (Enter_tcon (tcon), Be_Type_Tbl(MTYPE_I8));
00982 Allocate_Object(sym);
00983 if (Use_32_Bit_Pointers)
00984 Build_OP(TOP_lw, tmp, GP_TN,
00985 Gen_Symbol_TN(sym, 0, TN_RELOC_GOT_DISP), ops);
00986 else {
00987 Build_OP(TOP_ld, tmp, GP_TN,
00988 Gen_Symbol_TN(sym, 0, TN_RELOC_GOT_DISP), ops);
00989 }
00990 Build_OP(TOP_ld, tmp, tmp, Gen_Literal_TN(0, 4), ops);
00991 Build_OP (is_64bit ? TOP_daddu : TOP_addu, result, tmp, src2, ops);
00992 }
00993 return;
00994 }
00995 else FmtAssert(FALSE,("unexpected constant in Expand_Add"));
00996
00997 if (ISA_LC_Value_In_Class ( val, LC_simm16)) {
00998 new_opcode = is_64bit ? TOP_daddiu : TOP_addiu;
00999 Build_OP (new_opcode, result, src2, Gen_Literal_TN(val,4), ops);
01000 } else {
01001 src1 = Expand_Immediate_Into_Register (src1, is_64bit, ops);
01002 new_opcode = is_64bit ? TOP_dadd : TOP_addu;
01003 Build_OP (new_opcode, result, src2, src1, ops);
01004 }
01005 } else if (TN_is_constant(src2)) {
01006
01007 Expand_Add (result, src2, src1, mtype, ops);
01008 } else {
01009 Build_OP (is_64bit ? TOP_daddu : TOP_addu, result, src1, src2, ops);
01010 }
01011 }
01012
01013 void
01014 Expand_Sub (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01015 {
01016 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
01017 ("Expand_Sub: illegal result size\n"));
01018 TOP new_opcode;
01019 INT64 val;
01020 BOOL is_64bit = MTYPE_bit_size(mtype) == 64;
01021
01022 if (MTYPE_is_longlong(mtype)) {
01023 FmtAssert(Get_TN_Pair(result), ("Expand_Sub: result tn pair not setup"));
01024
01025 Expand_64Bit_ALU_OP(OPR_SUB, mtype, result, src1, src2, ops);
01026 return;
01027 }
01028 if (TN_is_constant(src2)) {
01029 if (TN_has_value(src2)) {
01030 val = - TN_value(src2);
01031 if (val == 0) {
01032 Expand_Copy (result, src1, mtype, ops);
01033 return;
01034 }
01035 }
01036 else if ( TN_is_symbol(src2) ) {
01037
01038 ST *base;
01039 INT64 val;
01040 Base_Symbol_And_Offset_For_Addressing (TN_var(src2), TN_offset(src2), &base, &val);
01041 val = - val;
01042 }
01043 else FmtAssert(FALSE,("unexpected constant in Expand_Sub"));
01044
01045 if (ISA_LC_Value_In_Class ( val, LC_simm16)) {
01046 new_opcode = is_64bit ? TOP_daddiu : TOP_addiu;
01047 Build_OP (new_opcode, result, src1, Gen_Literal_TN(val,4), ops);
01048 } else {
01049 src2 = Expand_Immediate_Into_Register (src2, is_64bit, ops);
01050 new_opcode = is_64bit ? TOP_dsubu : TOP_subu;
01051 Build_OP (new_opcode, result, src1, src2, ops);
01052 }
01053 }
01054 else if (TN_is_constant(src1)) {
01055 TN *tmp = Build_TN_Of_Mtype (mtype);
01056
01057 Expand_Sub (tmp, src2, src1, mtype, ops);
01058
01059 Build_OP(is_64bit ? TOP_dsubu : TOP_subu, result, Zero_TN, tmp, ops);
01060 }
01061 else {
01062 Build_OP (is_64bit ? TOP_dsubu : TOP_subu, result, src1, src2, ops);
01063 }
01064 }
01065
01066
01067 void
01068 Expand_Neg (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
01069 {
01070 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
01071 ("Expand_Neg: illegal result size\n"));
01072
01073 BOOL is_64bit = MTYPE_bit_size(mtype) == 64;
01074 if (MTYPE_is_float(mtype)) {
01075 if (MTYPE_is_double(mtype)) {
01076 TN* result_h = Get_TN_Pair(result);
01077 TN* src_h = Get_TN_Pair(src);
01078 FmtAssert(result_h && src_h, ("Expand_Neg: result_tn pair or src_tn pair not setup"));
01079 TN* imm_tn= Expand_Immediate_Into_Register(Gen_Literal_TN(0x80000000, 4), FALSE, ops);
01080 Build_OP(TOP_xor, result_h, src_h, imm_tn, ops);
01081 Build_OP(TOP_or, result, src, Zero_TN, ops);
01082
01083 } else {
01084 TN* imm_tn= Expand_Immediate_Into_Register(Gen_Literal_TN(0x80000000, 4), FALSE, ops);
01085 Build_OP(TOP_xor, result, src, imm_tn, ops);
01086 }
01087 } else {
01088 if (MTYPE_is_longlong(mtype)) {
01089 FmtAssert(Get_TN_Pair(result), ("Expand_Neg: result tn pair not setup"));
01090 Expand_64Bit_Unary_OP(OPR_NEG, mtype, result, src, ops );
01091 } else {
01092 Build_OP(TOP_subu, result, Zero_TN, src, ops);
01093 }
01094 }
01095 }
01096
01097 void
01098 Expand_Abs (TN *dest, TN *src, TYPE_ID mtype, OPS *ops)
01099 {
01100 BOOL is_double = MTYPE_is_size_double(mtype);
01101 if (!MTYPE_is_float(mtype)) {
01102 if (MTYPE_is_longlong(mtype)) {
01103 FmtAssert(Get_TN_Pair(dest) != NULL, ("result tn pair not setup in Expand_Abs\n"));
01104
01105 Expand_64Bit_Abs(dest, src, mtype, ops );
01106 } else {
01107 Build_OP(TOP_mc_abs, dest, src, ops);
01108 }
01109 }
01110 else {
01111 if (MTYPE_is_double(mtype)) {
01112 TN* dest_h = Get_TN_Pair(dest);
01113 TN* src_h = Get_TN_Pair(src);
01114 FmtAssert(dest_h && src_h, ("Expand_Abs: dest_tn pair or src_tn pair not setup"));
01115
01116
01117
01118 Build_OP(TOP_extrbu, dest_h, src_h, Gen_Literal_TN(30, 4), Gen_Literal_TN(31, 4), ops);
01119 Build_OP(TOP_or, dest, src, Zero_TN, ops);
01120
01121 } else {
01122
01123
01124 Build_OP(TOP_extrbu, dest, src, Gen_Literal_TN(30, 4), Gen_Literal_TN(31, 4), ops);
01125 }
01126 }
01127 }
01128
01129 void
01130 Expand_Shift (TN *result, TN *src1, TN *src2, TYPE_ID mtype, SHIFT_DIRECTION kind, OPS *ops)
01131 {
01132 WN *tree;
01133 TOP top;
01134 BOOL is_64bit = MTYPE_is_size_double(mtype);
01135
01136 if (is_64bit) {
01137 FmtAssert(Get_TN_Pair(result), ("Expand_Shift: result tn pair not setup"));
01138
01139 Expand_64Bit_Shift(kind, result, src1, src2, mtype, ops );
01140 return;
01141 }
01142
01143 if (TN_is_constant(src1))
01144 src1 = Expand_Immediate_Into_Register(src1, MTYPE_is_size_double(mtype), ops);
01145 if (TN_has_value(src2)) {
01146
01147 UINT64 val = TN_value(src2);
01148 switch (kind) {
01149 case shift_left:
01150 if (! is_64bit)
01151 top = TOP_sll;
01152 else if (val < 32)
01153 top = TOP_dsll;
01154 else top = TOP_dsll32;
01155 break;
01156 case shift_aright:
01157 if (! is_64bit)
01158 top = TOP_sra;
01159 else if (val < 32)
01160 top = TOP_dsra;
01161 else top = TOP_dsra32;
01162 break;
01163 case shift_lright:
01164 if (! is_64bit)
01165 top = TOP_srl;
01166 else if (val < 32)
01167 top = TOP_dsrl;
01168 else top = TOP_dsrl32;
01169 break;
01170 }
01171 Build_OP(top, result, src1, Gen_Literal_TN(val & 31, 4), ops);
01172 }
01173 else {
01174 switch (kind) {
01175 case shift_left:
01176 top = is_64bit ? TOP_dsllv : TOP_sllv;
01177 break;
01178
01179 case shift_aright:
01180 top = is_64bit ? TOP_dsrav : TOP_srav;
01181 break;
01182
01183 case shift_lright:
01184 top = is_64bit ? TOP_dsrlv : TOP_srlv;
01185 break;
01186 }
01187 Build_OP(top, result, src1, src2, ops);
01188 }
01189 }
01190
01191 inline void
01192 Expand_G_To_F (TN *ftn, TN *gtn, OPS *ops)
01193 { FmtAssert(FALSE,("Unimplemented")); }
01194
01195 inline void
01196 Expand_F_To_G (TN *gtn, TN *ftn, OPS *ops)
01197 { FmtAssert(FALSE,("Unimplemented")); }
01198
01199
01200
01201
01202
01203
01204
01205 static void shladd(TN *r, TN *x1, INT s, TN *x2, OPS *ops)
01206 {
01207 FmtAssert(s <= 31,("shladd: shift amount too large: %d",s));
01208 if (x2 == Zero_TN) {
01209 Build_OP(TN_size(r) == 8 ? TOP_dsll : TOP_sll, r, x1, Gen_Literal_TN(s, 4),
01210 ops);
01211 }
01212 else {
01213 TN *tmp_tn = Build_TN_Like(r);
01214 if (TN_size(r) == 8) {
01215 Build_OP(TOP_dsll, tmp_tn, x1, Gen_Literal_TN(s, 4), ops);
01216 Build_OP(TOP_daddu, r, tmp_tn, x2, ops);
01217 } else {
01218 Build_OP(TOP_sll, tmp_tn, x1, Gen_Literal_TN(s, 4), ops);
01219 Build_OP(TOP_addu, r, tmp_tn, x2, ops);
01220 }
01221 }
01222 }
01223
01224
01225
01226
01227
01228
01229
01230
01231 static void
01232 Expand_Small_Multiply(TN *r,
01233 TN *x,
01234 INT16 val,
01235 OPS * ops)
01236 {
01237 TN *r1;
01238 TN *r2;
01239 TN *Z=Zero_TN;
01240
01241 #define ONE_TEMP r1=Build_TN_Like(r)
01242 #define TWO_TEMPS ONE_TEMP; r2=Build_TN_Like(r)
01243
01244
01245 switch (val) {
01246 case -1:
01247 Expand_Neg(r,x,MTYPE_I8,ops);
01248 break;
01249 case 0:
01250 Expand_Copy (r, Z, MTYPE_I8, ops);
01251 break;
01252 case 1 :
01253 Expand_Copy (r, x, MTYPE_I8, ops);
01254 break;
01255 case 2 :
01256 shladd(r,x,1,Z,ops);
01257 break;
01258 case 3 :
01259 shladd(r,x,1,x,ops);
01260 break;
01261 case 4 :
01262 shladd(r,x,2,Z,ops);
01263 break;
01264 case 5 :
01265 shladd(r,x,2,x,ops);
01266 break;
01267 case 6:
01268 ONE_TEMP;
01269 Expand_Small_Multiply(r1,x,3,ops);
01270 Expand_Small_Multiply(r,r1,2,ops);
01271 break;
01272 case 7 :
01273 ONE_TEMP;
01274 shladd(r1,x,1,x,ops);
01275 shladd(r,r1,1,x,ops);
01276 break;
01277 case 8 :
01278 shladd(r,x,3,Z,ops);
01279 break;
01280 case 9 :
01281 shladd(r,x,3,x,ops);
01282 break;
01283 case 10 :
01284 ONE_TEMP;
01285 Expand_Small_Multiply(r1,x,5,ops);
01286 Expand_Small_Multiply(r,r1,2,ops);
01287 break;
01288 case 11 :
01289 ONE_TEMP;
01290 Expand_Small_Multiply(r1,x,9,ops);
01291 shladd(r,x,1,r1,ops);
01292 break;
01293 case 12 :
01294 ONE_TEMP;
01295 Expand_Small_Multiply(r1,x,3,ops);
01296 Expand_Small_Multiply(r,r1,4,ops);
01297 break;
01298 case 13 :
01299 ONE_TEMP;
01300 Expand_Small_Multiply(r1,x,5,ops);
01301 shladd(r,x,3,r1,ops);
01302 break;
01303 case 14 :
01304 TWO_TEMPS;
01305 Expand_Small_Multiply(r1,x,5,ops);
01306 Expand_Small_Multiply(r2,x,9,ops);
01307 Expand_Add(r,r1,r2,MTYPE_I8,ops);
01308 break;
01309 case 15 :
01310 ONE_TEMP;
01311 Expand_Small_Multiply(r1,x,3,ops);
01312 Expand_Small_Multiply(r,r1,5,ops);
01313 break;
01314 case 16 :
01315 shladd(r,x,4,Z,ops);
01316 break;
01317 case 17 :
01318 shladd(r,x,4,x,ops);
01319 break;
01320 case 18 :
01321 ONE_TEMP;
01322 Expand_Small_Multiply(r1,x,9,ops);
01323 Expand_Small_Multiply(r,r1,2,ops);
01324 break;
01325 case 19 :
01326 ONE_TEMP;
01327 Expand_Small_Multiply(r1,x,9,ops);
01328 shladd(r,r1,1,x,ops);
01329 break;
01330 case 20 :
01331 ONE_TEMP;
01332 Expand_Small_Multiply(r1,x,5,ops);
01333 Expand_Small_Multiply(r,r1,4,ops);
01334 break;
01335 case 21 :
01336 ONE_TEMP;
01337 Expand_Small_Multiply(r1,x,5,ops);
01338 shladd(r,x,4,r1,ops);
01339 break;
01340 case 22 :
01341 TWO_TEMPS;
01342 Expand_Small_Multiply(r1,x,17,ops);
01343 Expand_Small_Multiply(r2,x,5,ops);
01344 Expand_Add(r,r1,r2,MTYPE_I8,ops);
01345 break;
01346 case 23 :
01347 TWO_TEMPS;
01348 Expand_Small_Multiply(r1,x,17,ops);
01349 Expand_Small_Multiply(r2,x,3,ops);
01350 shladd(r,r2,1,r1,ops);
01351 break;
01352 case 24 :
01353 ONE_TEMP;
01354 Expand_Small_Multiply(r1,x,3,ops);
01355 Expand_Small_Multiply(r,r1,8,ops);
01356 break;
01357 case 25 :
01358 ONE_TEMP;
01359 Expand_Small_Multiply(r1,x,5,ops);
01360 Expand_Small_Multiply(r,r1,5,ops);
01361 break;
01362 case 26 :
01363 TWO_TEMPS;
01364 Expand_Small_Multiply(r1,x,17,ops);
01365 Expand_Small_Multiply(r2,x,9,ops);
01366 Expand_Add(r,r1,r2,MTYPE_I8,ops);
01367 break;
01368 case 27 :
01369 ONE_TEMP;
01370 Expand_Small_Multiply(r1,x,9,ops);
01371 Expand_Small_Multiply(r,r1,3,ops);
01372 break;
01373 case 28 :
01374 TWO_TEMPS;
01375 Expand_Small_Multiply(r1,x,3,ops);
01376 Expand_Small_Multiply(r2,x,4,ops);
01377 shladd(r,r1,3,r2,ops);
01378 break;
01379 case 29 :
01380 TWO_TEMPS;
01381 Expand_Small_Multiply(r1,x,3,ops);
01382 Expand_Small_Multiply(r2,x,5,ops);
01383 shladd(r,r1,3,r2,ops);
01384 break;
01385 case 30 :
01386 ONE_TEMP;
01387 Expand_Small_Multiply(r1,x,15,ops);
01388 Expand_Small_Multiply(r,r1,2,ops);
01389 break;
01390 case 31 :
01391 TWO_TEMPS;
01392 Expand_Small_Multiply(r1,x,16,ops);
01393 Expand_Small_Multiply(r2,x,-1,ops);
01394 shladd(r,r1,1,r2,ops);
01395 break;
01396 case 32 :
01397 ONE_TEMP;
01398 Expand_Small_Multiply(r1,x,16,ops);
01399 Expand_Small_Multiply(r,r1,2,ops);
01400 break;
01401 case 33 :
01402 ONE_TEMP;
01403 Expand_Small_Multiply(r1,x,16,ops);
01404 shladd(r,r1,1,x,ops);
01405 break;
01406 case 34 :
01407 ONE_TEMP;
01408 Expand_Small_Multiply(r1,x,17,ops);
01409 Expand_Small_Multiply(r,r1,2,ops);
01410 break;
01411 case 35 :
01412 ONE_TEMP;
01413 Expand_Small_Multiply(r1,x,17,ops);
01414 shladd(r,r1,1,x,ops);
01415 break;
01416 case 36 :
01417 ONE_TEMP;
01418 Expand_Small_Multiply(r1,x,9,ops);
01419 Expand_Small_Multiply(r,r1,4,ops);
01420 break;
01421 case 37 :
01422 ONE_TEMP;
01423 Expand_Small_Multiply(r1,x,9,ops);
01424 shladd(r,r1,2,x,ops);
01425 break;
01426 case 38 :
01427 TWO_TEMPS;
01428 Expand_Small_Multiply(r1,x,17,ops);
01429 Expand_Small_Multiply(r2,x,4,ops);
01430 shladd(r,r1,1,r2,ops);
01431 break;
01432 case 39 :
01433 TWO_TEMPS;
01434 Expand_Small_Multiply(r1,x,17,ops);
01435 Expand_Small_Multiply(r2,x,5,ops);
01436 shladd(r,r1,1,r2,ops);
01437 break;
01438 case 40 :
01439 ONE_TEMP;
01440 Expand_Small_Multiply(r1,x,5,ops);
01441 Expand_Small_Multiply(r,r1,8,ops);
01442 break;
01443 case 41 :
01444 ONE_TEMP;
01445 Expand_Small_Multiply(r1,x,5,ops);
01446 shladd(r,r1,3,x,ops);
01447 break;
01448 case 42 :
01449 TWO_TEMPS;
01450 Expand_Small_Multiply(r1,x,5,ops);
01451 Expand_Small_Multiply(r2,x,2,ops);
01452 shladd(r,r1,3,r2,ops);
01453 break;
01454 case 43 :
01455 TWO_TEMPS;
01456 Expand_Small_Multiply(r1,x,5,ops);
01457 Expand_Small_Multiply(r2,x,3,ops);
01458 shladd(r,r1,3,r2,ops);
01459 break;
01460 case 44 :
01461 TWO_TEMPS;
01462 Expand_Small_Multiply(r1,x,5,ops);
01463 Expand_Small_Multiply(r2,x,4,ops);
01464 shladd(r,r1,3,r2,ops);
01465 break;
01466 case 45 :
01467 ONE_TEMP;
01468 Expand_Small_Multiply(r1,x,5,ops);
01469 Expand_Small_Multiply(r,r1,9,ops);
01470 break;
01471 case 46 :
01472 ONE_TEMP;
01473 Expand_Small_Multiply(r1,x,45,ops);
01474 Expand_Add(r,r1,x,MTYPE_I8,ops);
01475 break;
01476 case 47 :
01477 TWO_TEMPS;
01478 Expand_Small_Multiply(r1,x,-1,ops);
01479 Expand_Small_Multiply(r2,x,3,ops);
01480 shladd(r,r2,4,r1,ops);
01481 break;
01482 case 48 :
01483 ONE_TEMP;
01484 Expand_Small_Multiply(r1,x,3,ops);
01485 Expand_Small_Multiply(r,r1,16,ops);
01486 break;
01487 case 49 :
01488 ONE_TEMP;
01489 Expand_Small_Multiply(r1,x,3,ops);
01490 shladd(r,r1,4,x,ops);
01491 break;
01492 case 50 :
01493 TWO_TEMPS;
01494 Expand_Small_Multiply(r1,x,3,ops);
01495 Expand_Small_Multiply(r2,x,2,ops);
01496 shladd(r,r1,4,r2,ops);
01497 break;
01498 case 51 :
01499 ONE_TEMP;
01500 Expand_Small_Multiply(r1,x,3,ops);
01501 Expand_Small_Multiply(r,r1,17,ops);
01502 break;
01503 case 52 :
01504 TWO_TEMPS;
01505 Expand_Small_Multiply(r1,x,3,ops);
01506 Expand_Small_Multiply(r2,x,4,ops);
01507 shladd(r,r1,4,r2,ops);
01508 break;
01509 case 53 :
01510 TWO_TEMPS;
01511 Expand_Small_Multiply(r1,x,3,ops);
01512 Expand_Small_Multiply(r2,x,5,ops);
01513 shladd(r,r1,4,r2,ops);
01514 break;
01515 case 54 :
01516 ONE_TEMP;
01517 Expand_Small_Multiply(r1,x,9,ops);
01518 Expand_Small_Multiply(r,r1,6,ops);
01519 break;
01520 case 55 :
01521 ONE_TEMP;
01522 Expand_Small_Multiply(r1,x,11,ops);
01523 Expand_Small_Multiply(r,r1,5,ops);
01524 break;
01525 case 56 :
01526 TWO_TEMPS;
01527 Expand_Small_Multiply(r1,x,3,ops);
01528 Expand_Small_Multiply(r2,x,8,ops);
01529 shladd(r,r1,4,r2,ops);
01530 break;
01531 case 57 :
01532 TWO_TEMPS;
01533 Expand_Small_Multiply(r1,x,3,ops);
01534 Expand_Small_Multiply(r2,x,9,ops);
01535 shladd(r,r1,4,r2,ops);
01536 break;
01537 case 58 :
01538 ONE_TEMP;
01539 Expand_Small_Multiply(r1,x,29,ops);
01540 Expand_Small_Multiply(r,r1,2,ops);
01541 break;
01542 case 59 :
01543 ONE_TEMP;
01544 Expand_Small_Multiply(r1,x,29,ops);
01545 shladd(r,r1,1,x,ops);
01546 break;
01547 case 60 :
01548 ONE_TEMP;
01549 Expand_Small_Multiply(r1,x,12,ops);
01550 Expand_Small_Multiply(r,r1,5,ops);
01551 break;
01552 case 61 :
01553 ONE_TEMP;
01554 Expand_Small_Multiply(r1,x,45,ops);
01555 shladd(r,x,4,r1,ops);
01556 break;
01557 case 62 :
01558 ONE_TEMP;
01559 Expand_Small_Multiply(r1,x,31,ops);
01560 Expand_Small_Multiply(r,r1,2,ops);
01561 break;
01562 case 63 :
01563 TWO_TEMPS;
01564 Expand_Small_Multiply(r1,x,-1,ops);
01565 Expand_Small_Multiply(r2,x,16,ops);
01566 shladd(r,r2,2,r1,ops);
01567 break;
01568 default:
01569 #pragma mips_frequency_hint NEVER
01570 FmtAssert(0,("Can't small multiply by %d",val));
01571
01572 }
01573 }
01574
01575
01576
01577
01578
01579
01580 static BOOL
01581 Expand_Multiply_Into_Shifts (
01582 TN *result_tn,
01583 TN *var_tn,
01584 TARG_UINT constant,
01585 INT16 limit,
01586 TYPE_ID mtype,
01587 OPS *ops)
01588 { FmtAssert(FALSE,("Unimplemented")); }
01589
01590
01591
01592
01593 #define NUM_FAST_MPYS 8
01594 static INT fast_mpys[NUM_FAST_MPYS] = {17,16,9,8,5,4,3,2};
01595
01596 static BOOL
01597 Expand_Constant_Multiply (TN *result, TN *var_tn, TARG_INT constant, TYPE_ID mtype, OPS *ops)
01598 {
01599 BOOL did_do_fast;
01600 INT16 limit;
01601 TN *x = var_tn;
01602 TN *r1 = Build_TN_Like(result);
01603 INT64 c = constant;
01604 BOOL needs_sign_extension;
01605
01606
01607 if (c == 0) {
01608 Expand_Copy (result, Zero_TN, mtype, ops);
01609 return TRUE;
01610 } else if (c == 1) {
01611 Expand_Copy (result, var_tn, mtype, ops);
01612 return TRUE;
01613 } else if (c == -1) {
01614 Expand_Neg(result, var_tn, mtype, ops);
01615 return TRUE;
01616 }
01617
01618 if (c < 0) {
01619 c = -c;
01620 x = Build_TN_Like(var_tn);
01621 Expand_Neg(x, var_tn, mtype, ops);
01622 }
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632 #if defined(TARG_SL)
01633 needs_sign_extension = MTYPE_size_reg(mtype) != 32;
01634 BOOL matched = FALSE;
01635 if(c<=5) {
01636 switch(c) {
01637 case 2:
01638 Expand_Shift(result, x, Gen_Literal_TN(1, 4), mtype, shift_left, ops);
01639 break;
01640 case 3:
01641 Expand_Shift(r1, x, Gen_Literal_TN(1, 4), mtype, shift_left, ops);
01642 Expand_Add(result, r1, x, mtype,ops);
01643 break;
01644 case 4:
01645 Expand_Shift(result, x, Gen_Literal_TN(2, 4), mtype, shift_left, ops);
01646 break;
01647 case 5:
01648 Expand_Shift(r1, x, Gen_Literal_TN(2, 4), mtype, shift_left, ops);
01649 Expand_Add(result, r1, x, mtype,ops);
01650 break;
01651 }
01652 matched = TRUE;
01653 }
01654 else {
01655 UINT shift_bit;
01656 UINT word_bit = HOST_WORD_SIZE * 8;
01657 for(shift_bit = 3; shift_bit<word_bit&&matched==FALSE; shift_bit++) {
01658 UINT sNumber = 1 << shift_bit;
01659 if(sNumber==c) {
01660 Expand_Shift(result, x, Gen_Literal_TN(shift_bit, 4), mtype, shift_left, ops);
01661 matched = TRUE;
01662 }
01663 else if(sNumber-1==c) {
01664 Expand_Shift(r1, x, Gen_Literal_TN(shift_bit, 4), mtype, shift_left, ops);
01665 Expand_Sub(result, r1, x, mtype,ops);
01666 matched = TRUE;
01667 }
01668 else if(sNumber+1==c) {
01669 Expand_Shift(r1, x, Gen_Literal_TN(shift_bit, 4), mtype, shift_left, ops);
01670 Expand_Add(result, r1, x, mtype,ops);
01671 matched = TRUE;
01672 }
01673 else if(sNumber-2==c) {
01674 Expand_Shift(r1, x, Gen_Literal_TN(shift_bit, 4), mtype, shift_left, ops);
01675 Expand_Sub(r1, r1, x,mtype,ops);
01676 Expand_Sub(result, r1, x, mtype,ops);
01677 matched = TRUE;
01678 }
01679 else if(sNumber+2==c) {
01680 Expand_Shift(r1, x, Gen_Literal_TN(shift_bit, 4), mtype, shift_left, ops);
01681 Expand_Add(r1, r1, x, mtype,ops);
01682 Expand_Add(result, r1, x, mtype,ops);
01683 matched = TRUE;
01684 }
01685 }
01686 }
01687 if(matched==TRUE) {
01688 if (needs_sign_extension) {
01689 TN *r2 = Build_TN_Like(result);
01690 Expand_Copy (r2, result, mtype, ops);
01691 Fixup_32_Bit_Op(result,r2,mtype,ops);
01692 }
01693 return TRUE;
01694 }
01695 else {
01696 return FALSE;
01697 }
01698
01699
01700
01701
01702 #else
01703
01704
01705 INT num_ones=0;
01706 UINT64 uc=c;
01707 while (uc) {num_ones += (uc&1); uc >>= 1;}
01708 uc = c;
01709 needs_sign_extension = MTYPE_size_reg(mtype) != 64;
01710
01711
01712
01713 if (uc <= 63) {
01714 if (needs_sign_extension) {
01715 Expand_Small_Multiply(result,x,uc,ops);
01716 } else {
01717 TN *r1 = Build_TN_Of_Mtype(MTYPE_I8);
01718 Expand_Small_Multiply(r1,x,uc,ops);
01719 Fixup_32_Bit_Op(result, r1, mtype,ops);
01720 }
01721 return TRUE;
01722 }
01723
01724
01725
01726
01727
01728
01729 INT first_1 = 0;
01730 while ((uc & 1) == 0) {++first_1; uc >>= 1;}
01731 if (first_1 != 0) {
01732 if (num_ones == 1) {
01733
01734 Expand_Shift(result, x, Gen_Literal_TN(first_1, 4), mtype, shift_left, ops);
01735 return TRUE;
01736 } else {
01737 TN *x1 = Dup_TN(x);
01738 Expand_Shift(x1, x, Gen_Literal_TN(first_1, 4), MTYPE_I8, shift_left, ops);
01739 x = x1;
01740 }
01741 }
01742
01743
01744
01745
01746
01747
01748
01749 if (uc == ((1<<num_ones)-1) && uc > 63) {
01750 TN *r1 = Dup_TN(result);
01751 Expand_Shift(r1, x, Gen_Literal_TN(num_ones, 4), MTYPE_I8, shift_left, ops);
01752 if (!needs_sign_extension) {
01753 Expand_Sub(result,r1,x,mtype,ops);
01754 } else {
01755 TN *r2 = Dup_TN(result);
01756 Expand_Sub(r2,r1,x,mtype,ops);
01757 Fixup_32_Bit_Op(result,r2,mtype,ops);
01758 }
01759 return TRUE;
01760 }
01761
01762
01763
01764
01765
01766 INT i;
01767 for (i=0; i < NUM_FAST_MPYS; i++) {
01768 INT mpy=fast_mpys[i];
01769 if (uc%mpy == 0 && uc/mpy <= 63) {
01770 INT64 uc1;
01771 TN *r1 = Dup_TN(result);
01772 Expand_Small_Multiply(r1,x,uc/mpy,ops);
01773 Expand_Constant_Multiply(result,r1,mpy,mtype,ops);
01774 return TRUE;
01775 }
01776 }
01777
01778
01779
01780
01781 TN *r = result;
01782 if (needs_sign_extension) {
01783 r = Dup_TN(result);
01784 }
01785
01786
01787
01788
01789
01790
01791 if (uc <= 63) {
01792 Expand_Small_Multiply(r,x,uc,ops);
01793 } else if (uc <= 1023) {
01794 INT64 uc1,uc2;
01795 TN *r1 = Dup_TN(result);
01796
01797
01798 uc1 = uc & 15;
01799 uc2 = uc >> 4;
01800
01801 Expand_Small_Multiply(r1,x,uc2,ops);
01802 if (uc1 == 0) {
01803 shladd(r,r1,4,Zero_TN,ops);
01804 } else if (uc1 == 1) {
01805 shladd(r,r1,4,x,ops);
01806 } else if (uc1 == uc2) {
01807 shladd(r,r1,4,r1,ops);
01808 } else {
01809 TN *r2 = Dup_TN(result);
01810 Expand_Small_Multiply(r2,x,uc1,ops);
01811 shladd(r,r1,4,r2,ops);
01812 }
01813 } else if (uc <= 65535) {
01814
01815
01816
01817
01818
01819
01820
01821 INT64 uc1,uc2;
01822 TN *r1 = Dup_TN(result);
01823 TN *r2 = Dup_TN(result);
01824 uc1 = uc & 255;
01825 uc2 = uc >> 8;
01826 Expand_Constant_Multiply (r1, x, uc2, MTYPE_I8, ops);
01827 if (uc1 == 0) {
01828 shladd(r2,r1,4,Zero_TN,ops);
01829 shladd(r,r2,4,Zero_TN,ops);
01830 } else if (uc1 == 1) {
01831 shladd(r2,r1,4,Zero_TN,ops);
01832 shladd(r,r2,4,x,ops);
01833
01834 } else if (uc1 == 16) {
01835 shladd(r2,r1,4,x,ops);
01836 shladd(r,r2,4,Zero_TN,ops);
01837
01838 } else if (uc1 == 17) {
01839 shladd(r2,r1,4,x,ops);
01840 shladd(r,r2,4,x,ops);
01841
01842 } else if (uc1 == uc2) {
01843 shladd(r2,r1,4,Zero_TN,ops);
01844 shladd(r,r2,4,r1,ops);
01845
01846 } else if (uc1 == 16*uc2) {
01847 shladd(r2,r1,4,r1,ops);
01848 shladd(r,r2,4,Zero_TN,ops);
01849
01850 } else if (uc1 == 17*uc2) {
01851 shladd(r2,r1,4,r1,ops);
01852 shladd(r,r2,4,r1,ops);
01853
01854 } else if (uc1%16 == 0) {
01855 TN *r3 = Dup_TN(result);
01856 uc1 /= 16;
01857 Expand_Constant_Multiply(r3,x,uc1,MTYPE_I8,ops);
01858 shladd(r2,r1,4,r3,ops);
01859 shladd(r,r2,4,Zero_TN,ops);
01860
01861 } else if (uc1%17 == 0) {
01862 TN *r3 = Dup_TN(result);
01863 uc1 /= 17;
01864 Expand_Constant_Multiply(r3,x,uc1,MTYPE_I8,ops);
01865 shladd(r2,r1,4,r3,ops);
01866 shladd(r,r2,4,r3,ops);
01867
01868 } else {
01869 TN *r3 = Dup_TN(result);
01870 Expand_Constant_Multiply(r3,x,uc1,MTYPE_I8,ops);
01871 shladd(r2,r1,4,Zero_TN,ops);
01872 shladd(r,r2,4,r3,ops);
01873 }
01874 } else if (uc <= ((1LL << 32)-1)) {
01875
01876
01877
01878
01879 INT64 uc1,uc2;
01880 TN *r1 = Dup_TN(result);
01881 TN *r2 = Dup_TN(result);
01882 TN *r3 = Dup_TN(result);
01883 uc1 = uc & 65535;
01884 uc2 = uc >> 16;
01885 Expand_Constant_Multiply(r1,x,uc1,MTYPE_I8,ops);
01886 Expand_Constant_Multiply(r2,x,uc2,MTYPE_I8,ops);
01887 Expand_Shift(r3,r2,Gen_Literal_TN(16, 4),MTYPE_I8,shift_left,ops);
01888 Expand_Add(r,r1,r3,MTYPE_I8,ops);
01889 } else {
01890
01891
01892
01893
01894
01895
01896
01897 INT64 uc1,uc2;
01898 TN *r1 = Dup_TN(result);
01899 TN *r2 = Dup_TN(result);
01900 TN *r3 = Dup_TN(result);
01901 uc1 = uc & 0xffffffff;
01902 uc2 = uc >> 32;
01903 Expand_Constant_Multiply(r1,x,uc1,MTYPE_I8,ops);
01904 Expand_Constant_Multiply(r2,x,uc2,MTYPE_I8,ops);
01905 Expand_Shift(r3,r2,Gen_Literal_TN(32, 4),MTYPE_I8,shift_left,ops);
01906 Expand_Add(r,r1,r3,MTYPE_I8,ops);
01907 }
01908
01909 if (needs_sign_extension) {
01910 Fixup_32_Bit_Op(result,r,mtype,ops);
01911 }
01912
01913 return TRUE;
01914 #endif // TARG_SL
01915 }
01916
01917 void
01918 Expand_Multiply (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01919 {
01920 TOP top;
01921 INT64 constant;
01922
01923 if (MTYPE_is_longlong(mtype)) {
01924 FmtAssert(Get_TN_Pair(result), ("Expand_Multiply: result tn pair not setup"));
01925 Expand_64Bit_ALU_OP(OPR_MPY, mtype, result, src1, src2, ops);
01926 return;
01927 }
01928
01929
01930
01931
01932
01933 if ((TN_has_value(src1) || TN_is_rematerializable(src1)) &&
01934 (TN_has_value(src2) || TN_is_rematerializable(src2))) {
01935
01936 TN *val_tn;
01937 constant = TN_has_value(src1) ? TN_value(src1) : WN_const_val(TN_home(src1));
01938 constant *= TN_has_value(src2) ? TN_value(src2) : WN_const_val(TN_home(src2));
01939
01940 constant = Targ_To_Host(Host_To_Targ(mtype,constant));
01941 #if defined(TARG_SL)
01942 val_tn = Gen_Literal_TN(constant, 4);
01943 #else
01944 val_tn = Gen_Literal_TN(constant, 8);
01945 #endif
01946 Exp_Immediate(result,val_tn,MTYPE_is_signed(mtype),ops);
01947 return;
01948 }
01949
01950 if (!Disable_Const_Mult_Opt && (TN_has_value(src1) || TN_has_value(src2) ||
01951 TN_is_rematerializable(src1) ||TN_is_rematerializable(src2))) {
01952 TN *var_tn;
01953 if ( TN_has_value(src1) || TN_is_rematerializable(src1) ) {
01954 constant = TN_has_value(src1) ? TN_value(src1) : WN_const_val(TN_home(src1));
01955 var_tn = src2;
01956 }
01957 else {
01958 constant = TN_has_value(src2) ? TN_value(src2) : WN_const_val(TN_home(src2));
01959 var_tn = src1;
01960 }
01961
01962 if (Can_Do_Fast_Multiply (mtype, constant)) {
01963 if (Expand_Constant_Multiply (result, var_tn, constant, mtype, ops)) {
01964
01965 return;
01966 }
01967 }
01968 }
01969 if (TN_has_value(src2)) {
01970 src2 = Expand_Immediate_Into_Register (src2, MTYPE_is_size_double(mtype), ops);
01971 }
01972
01973 FmtAssert(!TN_is_constant(src1),("Expand_Multiply: unexpected constant operand"));
01974 #if defined(TARG_SL)
01975 Is_True(!(MTYPE_is_size_double(mtype)), ("Expand_Multiply: unsupport 64-bit compute"));
01976
01977 if (CG_sl2) {
01978 top = TOP_c2_muls;
01979 } else {
01980 top = MTYPE_signed(mtype) ? TOP_c3_muls : TOP_c3_mulus;
01981 }
01982 #else
01983 if (! MTYPE_is_size_double(mtype))
01984 top = MTYPE_signed(mtype) ? TOP_mult : TOP_multu;
01985 else top = MTYPE_signed(mtype) ? TOP_dmult : TOP_dmultu;
01986 #endif
01987
01988 #if defined(TARG_SL)
01989 TN *zero_tn = Gen_Literal_TN(0, 4);
01990 if (CG_sl2) {
01991 TN *hi_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_cop_creg, 8, 0);
01992 Build_OP(top, result, hi_tn, src1, src2, zero_tn, Zero_TN, zero_tn, ops);
01993 } else {
01994 Build_OP(top, HI_TN, result, src1, src2,zero_tn,ops);
01995 }
01996 #else
01997 Build_OP(top, Hilo_TN(), src1, src2, ops);
01998 Build_OP(TOP_mflo, result, Hilo_TN(), ops);
01999 #endif
02000 }
02001
02002
02003 void
02004 Expand_High_Multiply (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02005 {
02006 TOP top;
02007 FmtAssert(!TN_is_constant(src1),("Expand_High_Multiply: unexpected constant operand"));
02008
02009 #if defined(TARG_SL)
02010 Is_True(!(MTYPE_is_size_double(mtype)), ("Expand_High_Multiply: unsupport 64-bit compute"));
02011 top = MTYPE_signed(mtype) ? TOP_c3_muls : TOP_c3_mulus;
02012 #else
02013 if (!MTYPE_is_size_double(mtype))
02014 top = MTYPE_signed(mtype) ? TOP_mult : TOP_multu;
02015 else top = MTYPE_signed(mtype) ? TOP_dmult : TOP_dmultu;
02016 #endif
02017
02018 if (TN_is_constant(src2))
02019 src2 = Expand_Immediate_Into_Register(src2, MTYPE_is_size_double(mtype), ops);
02020
02021 #if defined(TARG_SL)
02022 TN *lo_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
02023 TN *zero_tn = Gen_Literal_TN(0, 4);
02024 Build_OP(top, HI_TN, lo_tn, src1, src2, zero_tn, ops);
02025 Build_OP(TOP_c3_mvfs, result, HI_TN, zero_tn, ops);
02026 #else
02027 Build_OP(top, Hilo_TN(), src1, src2, ops);
02028 Build_OP(TOP_mfhi, result, Hilo_TN(), ops);
02029 #endif
02030 }
02031
02032 #if defined(TARG_SL)
02033 void Expand_MulShift_Hi (TN *result, TN *src1, TN *src2, TN *src3, TYPE_ID mtype, OPS *ops)
02034 {
02035 TOP top;
02036 TN *low_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
02037 TN *zero_tn = Gen_Literal_TN(0, 4);
02038 Is_True(!TN_is_constant(src1),("Expand_High_Multiply: unexpected constant operand"));
02039
02040 top = MTYPE_signed(mtype) ? TOP_c3_muls : TOP_c3_mulus;
02041
02042 if (TN_is_constant(src2))
02043 src2 = Expand_Immediate_Into_Register(src2, MTYPE_is_size_double(mtype), ops);
02044
02045 Is_True(TN_is_constant(src3) , ("shift value is constant"));
02046 Build_OP(top, HI_TN, low_tn, src1, src2, src3, ops);
02047 Build_OP(TOP_c3_mvfs, result, HI_TN, zero_tn, ops);
02048 }
02049
02050 void Expand_Unsigned_MulShift_Hi (TN *result, TN *src1, TN *src2, TN *src3, TYPE_ID mtype, OPS *ops)
02051 {
02052 TOP top;
02053 TN *low_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
02054 TN *zero_tn = Gen_Literal_TN(0, 4);
02055 Is_True(!TN_is_constant(src1),("Expand_Unsigned_MulShift_Hi: unexpected constant operand"));
02056 Is_True(MTYPE_is_unsigned(mtype), ("Expand_Unsigned_MulShift_Hi: should be unsigned"));
02057 top = MTYPE_signed(mtype) ? TOP_c3_muls : TOP_c3_mulus;
02058
02059 if (TN_is_constant(src2))
02060 src2 = Expand_Immediate_Into_Register(src2, MTYPE_is_size_double(mtype), ops);
02061
02062 Is_True(TN_is_constant(src3) , ("shift value is constant"));
02063 Build_OP(top, HI_TN, low_tn, src1, src2, src3, ops);
02064 Build_OP(TOP_c3_mvfs, result, HI_TN, zero_tn, ops);
02065 }
02066
02067 void Expand_Mulshift (TN *result, TN *src1, TN *src2, TN *src3, TYPE_ID mtype, OPS *ops) {
02068 Is_True(TN_has_value(src3), ("Expand_Mulshift:: shift num must be immediate"));
02069
02070 TOP top;
02071 INT64 constant;
02072 UINT shift = TN_value(src3);
02073
02074
02075
02076
02077 if ((TN_has_value(src1) || TN_is_rematerializable(src1)) &&
02078 (TN_has_value(src2) || TN_is_rematerializable(src2))) {
02079
02080 TN *val_tn;
02081 constant = TN_has_value(src1) ? TN_value(src1) : WN_const_val(TN_home(src1));
02082 constant *= TN_has_value(src2) ? TN_value(src2) : WN_const_val(TN_home(src2));
02083
02084 constant = Targ_To_Host(Host_To_Targ(mtype,constant));
02085 if (shift > 0) {
02086 constant = (constant << shift);
02087 }
02088 val_tn = Gen_Literal_TN(constant, 4);
02089 Exp_Immediate(result,val_tn,MTYPE_is_signed(mtype),ops);
02090 return;
02091 }
02092
02093 if (!Disable_Const_Mult_Opt && (TN_has_value(src1) || TN_has_value(src2) ||
02094 TN_is_rematerializable(src1) ||TN_is_rematerializable(src2))) {
02095 TN *var_tn;
02096 if ( TN_has_value(src1) || TN_is_rematerializable(src1) ) {
02097 constant = TN_has_value(src1) ? TN_value(src1) : WN_const_val(TN_home(src1));
02098 var_tn = src2;
02099 }
02100 else {
02101 constant = TN_has_value(src2) ? TN_value(src2) : WN_const_val(TN_home(src2));
02102 var_tn = src1;
02103 }
02104
02105 if (Can_Do_Fast_Multiply (mtype, constant)) {
02106 if (shift > 0) {
02107 TN *tmp = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
02108 if (Expand_Constant_Multiply(tmp, var_tn, constant, mtype, ops)) {
02109 Expand_Shift(result, tmp, src3, mtype, shift_left, ops);
02110 return;
02111 }
02112 } else {
02113 if (Expand_Constant_Multiply (result, var_tn, constant, mtype, ops)) {
02114
02115 return;
02116 }
02117 }
02118 }
02119 }
02120 if (TN_has_value(src2)) {
02121 src2 = Expand_Immediate_Into_Register (src2, MTYPE_is_size_double(mtype), ops);
02122 }
02123
02124 FmtAssert(!TN_is_constant(src1),("Expand_Multiply: unexpected constant operand"));
02125 Is_True(!(MTYPE_is_size_double(mtype)), ("Expand_Multiply: unsupport 64-bit compute"));
02126
02127 top = MTYPE_signed(mtype) ? TOP_c3_muls : TOP_c3_mulus;
02128 Build_OP(top, HI_TN, result, src1, src2, src3, ops);
02129 }
02130
02131 TN *Expand_Mul_Shift (WN *intrncall, TN *result, OPS *ops, BOOL highpart=FALSE) {
02132 Is_True( (WN_kid0(intrncall)!=NULL && WN_kid1(intrncall)!=NULL && WN_kid2(intrncall)!=NULL),
02133 ("Expand_Mul_Shift:: one parameter is null"));
02134
02135 TN *kid0_tn, *kid1_tn;
02136 TYPE_ID rtype0, rtype1, rtype;
02137 INT32 value;
02138
02139 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall)),
02140 ("Expand_C3_SAVE_ACC:: operand is null"));
02141
02142 kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
02143 kid1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
02144 value = WN_const_val(WN_kid0(WN_kid2(intrncall)));
02145 rtype0 = WN_rtype(WN_kid0(intrncall));
02146 rtype1 = WN_rtype(WN_kid1(intrncall));
02147 rtype = rtype1;
02148 if ((rtype0 == MTYPE_U4) && (rtype1 != MTYPE_U4)) {
02149 rtype = rtype0;
02150 }
02151
02152 if (highpart)
02153 Expand_MulShift_Hi(result, kid0_tn, kid1_tn, Gen_Literal_TN(value, 4), rtype, ops);
02154 else
02155 Expand_Mulshift(result, kid0_tn, kid1_tn, Gen_Literal_TN(value, 4), rtype, ops);
02156 return result;
02157
02158 }
02159
02160
02161
02162 TN *Build_C3_Intrinsic_OP( INTRINSIC id, WN* intrncall, OPS *ops, TN *result )
02163 {
02164 switch(id) {
02165 case INTRN_CVT64_HIGH:
02166 case INTRN_CVT64_LOW:
02167 return Expand_Float64_Const(intrncall, result, id == INTRN_CVT64_HIGH, ops);
02168 case INTRN_LONGLONG_CVT64_HIGH:
02169 case INTRN_LONGLONG_CVT64_LOW:
02170 return Expand_LONGLONG_Const(intrncall, result, id == INTRN_LONGLONG_CVT64_HIGH, ops);
02171 case INTRN_CVT32:
02172 return Expand_Float32_Const(intrncall, result, ops);
02173 case INTRN_C3_INIT_ACC:
02174 return Expand_C3_INIT_ACC(intrncall, result, ops);
02175 case INTRN_C3_SAVE_ACC:
02176 return Expand_C3_SAVE_ACC(intrncall, result, ops);
02177 case INTRN_C3_MVFS:
02178 return Expand_C3_MVFS(intrncall, result, ops);
02179 case INTRN_C3_INIT_ADDR:
02180 return Expand_INIT_ADDR(intrncall, result, ops);
02181 case INTRN_C3_SAVE_ADDR:
02182 return Expand_SAVE_ADDR(intrncall, result, ops);
02183 case INTRN_C3_INIT_DACC:
02184 return Expand_C3_INIT_DACC(intrncall, result, ops);
02185 case INTRN_C3_SAVE_DACC:
02186 return Expand_C3_SAVE_DACC(intrncall, result, ops);
02187 case INTRN_C3_PTR:
02188 return Expand_C3_PTR(intrncall, result, ops);
02189 case INTRN_C3_SET_ADDR:
02190 return Expand_SET_ADDRSIZE(intrncall, result, ops);
02191 case INTRN_C3_SET_CIRCBUF:
02192 return Expand_Set_CircBuf(intrncall, result, ops);
02193 case INTRN_C3AADDA:
02194 return Expand_C3_aadda(intrncall, result, ops);
02195 case INTRN_C3BITR:
02196 return Expand_C3_bitr(intrncall, result, ops);
02197 case INTRN_C3CS:
02198 return Expand_C3_cs(intrncall, result, ops);
02199 case INTRN_C3DADD:
02200 return Expand_C3_Mode0(TOP_c3_dadd, intrncall, result, 0, ops, TRUE);
02201 case INTRN_C3SAADDS:
02202 return Expand_C3_Mode0(TOP_c3_saadds, intrncall, result, 1, ops, TRUE);
02203 case INTRN_C3SAADDSH:
02204 return Expand_C3_Mode0(TOP_c3_saaddsh, intrncall, result, 1, ops, TRUE);
02205 case INTRN_C3SAMULSH:
02206 return Expand_C3_Mode0(TOP_c3_samulsh, intrncall, result, 1, ops, FALSE);
02207 case INTRN_C3FFE:
02208 return Expand_C3_FFE(intrncall, result, ops);
02209 case INTRN_C3DMAC:
02210 return Expand_C3_Mode2(TOP_c3_dmac, intrncall, result, 3, ops);
02211 case INTRN_C3DMULA:
02212 return Expand_C3_Mode2(TOP_c3_dmula, intrncall, result, 2, ops);
02213 case INTRN_C3MAC:
02214 return Expand_C3_Mode1(TOP_c3_mac, intrncall, result, 1, ops);
02215 case INTRN_C3MULA:
02216 return Expand_C3_Mode1(TOP_c3_mula, intrncall, result, 0, ops);
02217 case INTRN_C3MAC_A:
02218 return Expand_C3_Mode3(TOP_c3_mac_a, intrncall, result, 1, ops, TRUE);
02219 case INTRN_C3MULA_A:
02220 return Expand_C3_Mode3(TOP_c3_mula_a, intrncall, result, 0, ops, FALSE);
02221 case INTRN_C3MAC_AR:
02222 return Expand_C3_Mode4(TOP_c3_mac_ar, intrncall, result, 1, ops, TRUE);
02223 case INTRN_C3MULA_AR:
02224 return Expand_C3_Mode4(TOP_c3_mula_ar, intrncall, result, 0, ops, FALSE);
02225 case INTRN_C3MAC_I:
02226 return Expand_C3_Mode5(TOP_c3_mac_i, intrncall, result, 2, ops, TRUE);
02227 case INTRN_C3SADDA:
02228 return Expand_C3_Mode5(TOP_c3_sadda, intrncall, result, 4, ops, FALSE);
02229 case INTRN_C3SHAV:
02230 return Expand_C3_Mode5(TOP_c3_shav, intrncall, result, 1, ops, FALSE);
02231 case INTRN_C3MULA_I:
02232 return Expand_C3_Mode5(TOP_c3_mula_i, intrncall, result, 1, ops, FALSE);
02233 case INTRN_C3SHLATA_I:
02234 return Expand_C3_Mode5(TOP_c3_shlata_i, intrncall, result, 2, ops, TRUE);
02235 case INTRN_C3ROUND:
02236 return Expand_C3_Mode6(TOP_c3_round, intrncall, result, 2, ops, FALSE);
02237 case INTRN_C3SHLA_I:
02238 return Expand_C3_Mode6(TOP_c3_shla_i, intrncall, result, 2, ops, TRUE);
02239 case INTRN_C3SAADD_A:
02240 return Expand_C3_Mode7(TOP_c3_saadd_a, intrncall, result, 0, ops, TRUE);
02241 case INTRN_C3SAADDH_A:
02242 return Expand_C3_Mode7(TOP_c3_saaddh_a, intrncall, result, 0, ops, TRUE);
02243 case INTRN_C3SAMULH_A:
02244 return Expand_C3_Mode7(TOP_c3_samulh_a, intrncall, result, 0, ops, FALSE);
02245 case INTRN_C3DMAC_A:
02246 return Expand_C3_Mode8(TOP_c3_dmac_a, intrncall, result, 2, ops, TRUE);
02247 case INTRN_C3DMULA_A:
02248 return Expand_C3_Mode8(TOP_c3_dmula_a, intrncall, result, 1, ops, TRUE);
02249 case INTRN_C3DSHLL_I:
02250 return Expand_C3_Mode9(TOP_c3_dshll_i, intrncall, result, 2, ops, TRUE);
02251 case INTRN_C3REVB:
02252 return Expand_C3_Mode9(TOP_c3_revb, intrncall, result, 1, ops, FALSE);
02253 case INTRN_C3LD:
02254 return Expand_C3_Mode10(TOP_c3_ld, intrncall, result, 0, ops, TRUE);
02255 case INTRN_C3ST:
02256 return Expand_C3_Mode11(TOP_c3_st, intrncall, result, 0, ops, TRUE);
02257 case INTRN_C3LEAD:
02258 return Expand_C3_lead(intrncall, result, ops);
02259 case INTRN_C3SHLAFA_I:
02260 return Expand_C3_shlafa_i(intrncall, result, ops);
02261 case INTRN_C3SADDA_A:
02262 return Expand_C3_saadda_a(intrncall, result, ops);
02263 case INTRN_C3SUBC:
02264 return Expand_C3_subc(intrncall, result, ops);
02265 case INTRN_C3NEGA:
02266 return Expand_C3_nega(intrncall, result, ops);
02267 case INTRN_C3MULS:
02268 return Expand_C3_mul(TOP_c3_muls, intrncall, result, ops);
02269 case INTRN_C3MULUS:
02270 return Expand_C3_mul(TOP_c3_mulus, intrncall, result, ops);
02271 case INTRN_INIT_HI:
02272 return Expand_Init_HI(intrncall, result, ops);
02273 case INTRN_COPY_HI:
02274 return Expand_Copy_HI(intrncall, result, ops);
02275 default:
02276 Is_True(0, ("Build_C3_Intrinsic_OP:: no such c3 intrinsic function"));
02277 }
02278 }
02279 #endif
02280
02281 void
02282 Expand_Logical_Not (TN *dest, TN *src, VARIANT variant, OPS *ops)
02283 {
02284
02285 Build_OP (TOP_xori, dest, src, Gen_Literal_TN(1, 4), ops);
02286 }
02287
02288 void
02289 Expand_Logical_And (TN *dest, TN *src1, TN *src2, VARIANT variant, OPS *ops)
02290 {
02291 Build_OP (TOP_and, dest, src1, src2, ops);
02292 }
02293
02294 void
02295 Expand_Logical_Or (TN *dest, TN *src1, TN *src2, VARIANT variant, OPS *ops)
02296 {
02297 Build_OP (TOP_or, dest, src1, src2, ops);
02298 }
02299
02300
02301 void
02302 Expand_Binary_Complement (TN *dest, TN *src, TYPE_ID mtype, OPS *ops)
02303 {
02304 if (MTYPE_is_longlong(mtype)) {
02305 FmtAssert(Get_TN_Pair(dest), ("Expand_Binary_Complement: result tn pair not setup"));
02306 Expand_64Bit_Unary_OP(OPR_BNOT, MTYPE_I8, dest, src, ops);
02307 }
02308 else {
02309 Build_OP(TOP_nor, dest, src, Zero_TN, ops);
02310 }
02311 }
02312
02313 void
02314 Expand_Binary_And (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02315 {
02316 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
02317 ("Expand_Binary_And: illegal result size\n"));
02318
02319 if (MTYPE_is_longlong(mtype)) {
02320 FmtAssert(Get_TN_Pair(dest), ("Expand_Binary_And: result tn pair not setup"));
02321 Expand_64Bit_BitLogic_OP(OPR_BAND, mtype, dest, src1, src2, ops);
02322 return;
02323 }
02324
02325 if (TN_is_constant(src1)) {
02326 INT64 val;
02327 if (TN_has_value(src1)) {
02328 val = TN_value(src1);
02329 if (val == -1) {
02330 Expand_Copy (dest, src2, mtype, ops);
02331 return;
02332 }
02333 }
02334 else FmtAssert(FALSE,("unexpected constant in Expand_Binary_And"));
02335
02336 TOP new_opcode;
02337 if (ISA_LC_Value_In_Class ( val, LC_uimm16))
02338 new_opcode = TOP_andi;
02339 else {
02340 src1 = Expand_Immediate_Into_Register(src1, MTYPE_bit_size(mtype) == 64,
02341 ops);
02342 new_opcode = TOP_and;
02343 }
02344 Build_OP (new_opcode, dest, src2, src1, ops);
02345 }
02346 else if (TN_is_constant(src2)) {
02347
02348 Expand_Binary_And (dest, src2, src1, mtype, ops);
02349 }
02350 else {
02351 Build_OP (TOP_and, dest, src1, src2, ops);
02352 }
02353 }
02354
02355 void
02356 Expand_Binary_Or (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02357 {
02358 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
02359 ("Expand_Binary_Or: illegal dest size\n"));
02360
02361 if (MTYPE_is_longlong(mtype)) {
02362 FmtAssert(Get_TN_Pair(dest), ("Expand_Binary_Or: result tn pair not setup"));
02363 Expand_64Bit_BitLogic_OP(OPR_BIOR, mtype, dest, src1, src2, ops);
02364 return;
02365 }
02366
02367 if (TN_is_constant(src1)) {
02368 INT64 val;
02369 if (TN_has_value(src1)) {
02370 val = TN_value(src1);
02371 if (val == 0) {
02372 Expand_Copy (dest, src2, mtype, ops);
02373 return;
02374 }
02375 }
02376 else FmtAssert(FALSE,("unexpected constant in Expand_Binary_Or"));
02377
02378 TOP new_opcode;
02379 if (ISA_LC_Value_In_Class ( val, LC_uimm16))
02380 new_opcode = TOP_ori;
02381 else {
02382 src1 = Expand_Immediate_Into_Register(src1, MTYPE_bit_size(mtype) == 64,
02383 ops);
02384 new_opcode = TOP_or;
02385 }
02386 Build_OP (new_opcode, dest, src2, src1, ops);
02387 }
02388 else if (TN_is_constant(src2)) {
02389
02390 Expand_Binary_Or (dest, src2, src1, mtype, ops);
02391 }
02392 else {
02393 Build_OP (TOP_or, dest, src1, src2, ops);
02394 }
02395 }
02396
02397 void
02398 Expand_Binary_Xor (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02399 {
02400 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
02401 ("Expand_Binary_Xor: illegal dest size\n"));
02402
02403 if (MTYPE_is_longlong(mtype)) {
02404 FmtAssert(Get_TN_Pair(dest), ("Expand_Binary_Xor: result tn pair not setup"));
02405 Expand_64Bit_BitLogic_OP(OPR_BXOR, mtype, dest, src1, src2, ops);
02406 return;
02407 }
02408
02409 if (TN_is_constant(src1)) {
02410 INT64 val;
02411 if (TN_has_value(src1))
02412 val = TN_value(src1);
02413 else FmtAssert(FALSE,("unexpected constant in Expand_Binary_Xor"));
02414 if (val == 0 && src1 == dest)
02415 return;
02416
02417 TOP new_opcode;
02418 if (ISA_LC_Value_In_Class ( val, LC_uimm16))
02419 new_opcode = TOP_xori;
02420 else {
02421 src1 = Expand_Immediate_Into_Register(src1, MTYPE_bit_size(mtype) == 64,
02422 ops);
02423 new_opcode = TOP_xor;
02424 }
02425 Build_OP (new_opcode, dest, src2, src1, ops);
02426 }
02427 else if (TN_is_constant(src2)) {
02428
02429 Expand_Binary_Xor (dest, src2, src1, mtype, ops);
02430 }
02431 else {
02432 Build_OP (TOP_xor, dest, src1, src2, ops);
02433 }
02434 }
02435
02436 void
02437 Expand_Binary_Nor (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02438 {
02439 if (MTYPE_is_longlong(mtype)) {
02440 FmtAssert(Get_TN_Pair(dest), ("Expand_Binary_Nor: result tn pair not setup"));
02441 Expand_64Bit_BitLogic_OP(OPR_BNOR, mtype, dest, src1, src2, ops);
02442 } else
02443 Build_OP (TOP_nor, dest, src1, src2, ops);
02444 }
02445
02446 static void
02447 Expand_32Bit_Int_Less (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02448 {
02449 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
02450 ("Expand_Int_Less: illegal dest size\n"));
02451 if (TN_is_constant(src2)) {
02452 INT64 val;
02453 if (TN_has_value(src2))
02454 val = TN_value(src2);
02455 else if ( TN_is_symbol(src2) ) {
02456
02457 ST *base;
02458 INT64 val;
02459 Base_Symbol_And_Offset_For_Addressing (TN_var(src2), TN_offset(src2), &base, &val);
02460 }
02461 else FmtAssert(FALSE,("unexpected constant in Expand_Int_Less"));
02462
02463 TOP new_opcode;
02464 if (ISA_LC_Value_In_Class ( val, LC_simm16))
02465 new_opcode = MTYPE_signed(mtype) ? TOP_slti : TOP_sltiu;
02466 else {
02467 src2 = Expand_Immediate_Into_Register(src2, MTYPE_bit_size(mtype) == 64,
02468 ops);
02469 new_opcode = MTYPE_signed(mtype) ? TOP_slt : TOP_sltu;
02470 }
02471 Build_OP (new_opcode, dest, src1, src2, ops);
02472 }
02473 else
02474 Build_OP (MTYPE_signed(mtype) ? TOP_slt : TOP_sltu, dest, src1, src2, ops);
02475 }
02476
02477 static void
02478 Expand_32Bit_Int_Less_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02479 {
02480 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
02481 ("Expand_Int_Less_Equal: illegal dest size\n"));
02482 if (TN_is_constant(src2)) {
02483 INT64 val;
02484 if (TN_has_value(src2))
02485 val = TN_value(src2);
02486 #if 0 // I doubt this case is working (fchow mar-12-03)
02487 else if ( TN_is_symbol(src2) ) {
02488
02489 ST *base;
02490 INT64 val;
02491 Base_Symbol_And_Offset_For_Addressing (TN_var(src2), TN_offset(src2), &base, &val);
02492 }
02493 #endif
02494 else FmtAssert(FALSE,("unexpected constant in Expand_Int_Less_Equal"));
02495
02496 if (ISA_LC_Value_In_Class ( val+1, LC_simm16)) {
02497 Build_OP(MTYPE_signed(mtype) ? TOP_slti : TOP_sltiu, dest, src1,
02498 Gen_Literal_TN(val+1, 4), ops);
02499 }
02500 else {
02501 INT size = MTYPE_byte_size(mtype);
02502 src2 = Expand_Immediate_Into_Register(Gen_Literal_TN(val+1, size),
02503 size == 8, ops);
02504 Build_OP(MTYPE_signed(mtype) ? TOP_slt : TOP_sltu, dest, src1, src2, ops);
02505 }
02506 }
02507 else {
02508 TN *tmp = Build_TN_Of_Mtype(mtype);
02509 Build_OP (MTYPE_signed(mtype) ? TOP_slt : TOP_sltu, tmp, src2, src1, ops);
02510 Build_OP (TOP_xori, dest, tmp, Gen_Literal_TN(1, 4), ops);
02511 }
02512 }
02513
02514 static void
02515 Expand_32Bit_Int_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02516 {
02517 TN *tmp_tn;
02518 if ((TN_size(dest) == MTYPE_byte_size(mtype)) &&
02519 !TN_is_dedicated(dest))
02520 tmp_tn = dest;
02521 else tmp_tn = Gen_Typed_Register_TN(mtype, MTYPE_byte_size(mtype));
02522 Expand_Binary_Xor(tmp_tn, src1, src2, mtype, ops);
02523 Build_OP (TOP_sltiu, dest, tmp_tn, Gen_Literal_TN(1, 4), ops);
02524 }
02525
02526 static void
02527 Expand_32Bit_Int_Not_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02528 {
02529 TN *tmp_tn;
02530 if ((TN_size(dest) == MTYPE_byte_size(mtype)) &&
02531 !TN_is_dedicated(dest))
02532 tmp_tn = dest;
02533 else tmp_tn = Gen_Typed_Register_TN(mtype, MTYPE_byte_size(mtype));
02534 Expand_Binary_Xor(tmp_tn, src1, src2, mtype, ops);
02535 Build_OP (TOP_sltu, dest, Zero_TN, tmp_tn, ops);
02536 }
02537
02538 static void
02539 Expand_32Bit_Int_Greater_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02540 {
02541 TN *tmp_tn;
02542 if ((TN_size(dest) == MTYPE_byte_size(mtype)) &&
02543 !TN_is_dedicated(dest))
02544 tmp_tn = dest;
02545 else tmp_tn = Gen_Typed_Register_TN(mtype, MTYPE_byte_size(mtype));
02546 Expand_Int_Less(tmp_tn, src1, src2, mtype, ops);
02547 Build_OP (TOP_xori, dest, tmp_tn, Gen_Literal_TN(1, 4), ops);
02548 }
02549
02550 static void
02551 Expand_32Bit_Int_Greater (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02552 {
02553 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
02554 ("Expand_Int_Greater: illegal dest size\n"));
02555 if (TN_is_constant(src1))
02556 src1 = Expand_Immediate_Into_Register(src1, MTYPE_bit_size(mtype)==64, ops);
02557 if (TN_is_constant(src2))
02558 src2 = Expand_Immediate_Into_Register(src2, MTYPE_bit_size(mtype)==64, ops);
02559 Build_OP (MTYPE_signed(mtype) ? TOP_slt : TOP_sltu, dest, src2, src1, ops);
02560 }
02561
02562 static void
02563 Expand_Int_Compare(OPERATOR cmp, TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02564 {
02565 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
02566 ("Expand_Int_Cmp: illegal dest size\n"));
02567
02568 switch (cmp) {
02569 case OPR_LT:
02570 if (MTYPE_is_longlong(mtype)) {
02571 Expand_64Bit_Int_Less(dest, src1, src2, mtype, ops);
02572 } else {
02573 Expand_32Bit_Int_Less(dest, src1, src2, mtype, ops);
02574 }
02575 break;
02576 case OPR_LE:
02577 if (MTYPE_is_longlong(mtype)) {
02578 Expand_64Bit_Int_Less_Equal(dest, src1, src2, mtype, ops);
02579 } else {
02580 Expand_32Bit_Int_Less_Equal(dest, src1, src2, mtype, ops);
02581 }
02582 break;
02583 case OPR_EQ:
02584 if (MTYPE_is_longlong(mtype)) {
02585 Expand_64Bit_Int_Equal(dest, src1, src2, mtype, ops);
02586 } else {
02587 Expand_32Bit_Int_Equal(dest, src1, src2, mtype, ops);
02588 }
02589 break;
02590 case OPR_NE:
02591 if (MTYPE_is_longlong(mtype)) {
02592 Expand_64Bit_Int_Not_Equal(dest, src1, src2, mtype, ops);
02593 } else {
02594 Expand_32Bit_Int_Not_Equal(dest, src1, src2, mtype, ops);
02595 }
02596 break;
02597 case OPR_GE:
02598 if (MTYPE_is_longlong(mtype)) {
02599 Expand_64Bit_Int_Greater_Equal(dest, src1, src2, mtype, ops);
02600 } else {
02601 Expand_32Bit_Int_Greater_Equal(dest, src1, src2, mtype, ops);
02602 }
02603 break;
02604 case OPR_GT:
02605 if (MTYPE_is_longlong(mtype)) {
02606 Expand_64Bit_Int_Greater(dest, src1, src2, mtype, ops);
02607 } else {
02608 Expand_32Bit_Int_Greater(dest, src1, src2, mtype, ops);
02609 }
02610 break;
02611 default:
02612 FmtAssert(FALSE, ("Expand_Int_Compare: invalid compare operator!"));
02613 }
02614
02615
02616 TN *dest_high = Get_TN_Pair(dest);
02617 if (dest_high) {
02618 Build_OP(TOP_or, dest_high, Zero_TN, Zero_TN, ops);
02619 }
02620 }
02621
02622 void
02623 Expand_Int_Less (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02624 {
02625 Expand_Int_Compare(OPR_LT, dest, src1, src2, mtype, ops);
02626 }
02627
02628 void
02629 Expand_Int_Less_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02630 {
02631 Expand_Int_Compare(OPR_LE, dest, src1, src2, mtype, ops);
02632 }
02633
02634 void
02635 Expand_Int_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02636 {
02637 Expand_Int_Compare(OPR_EQ, dest, src1, src2, mtype, ops);
02638 }
02639
02640 void
02641 Expand_Int_Not_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02642 {
02643 Expand_Int_Compare(OPR_NE, dest, src1, src2, mtype, ops);
02644 }
02645
02646 void
02647 Expand_Int_Greater_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02648 {
02649 Expand_Int_Compare(OPR_GE, dest, src1, src2, mtype, ops);
02650 }
02651
02652 void
02653 Expand_Int_Greater (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02654 {
02655 Expand_Int_Compare(OPR_GT, dest, src1, src2, mtype, ops);
02656 }
02657
02658 static void
02659 Expand_Bool_Comparison (BOOL equals, TN *dest, TN *src1, TN *src2, OPS *ops)
02660 { FmtAssert(FALSE,("Unimplemented")); }
02661
02662 void
02663 Expand_Bool_Equal (TN *dest, TN *src1, TN *src2, OPS *ops)
02664 { FmtAssert(FALSE,("Unimplemented")); }
02665
02666 void
02667 Expand_Bool_Not_Equal (TN *dest, TN *src1, TN *src2, OPS *ops)
02668 { FmtAssert(FALSE,("Unimplemented")); }
02669
02670 void
02671 Expand_Bool_To_Int (TN *dest, TN *src, TYPE_ID rtype, OPS *ops)
02672 { FmtAssert(FALSE,("Unimplemented")); }
02673
02674 typedef enum {
02675 ROUND_USER,
02676 ROUND_NEAREST,
02677 ROUND_CHOP,
02678 ROUND_NEG_INF,
02679 ROUND_PLUS_INF
02680 } ROUND_MODE;
02681
02682
02683 static void
02684 Expand_Float_To_Int (ROUND_MODE rm, TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
02685 {
02686 TOP top;
02687 BOOL int_64bit = MTYPE_byte_size(imtype) == 8;
02688 if (fmtype == MTYPE_F4) {
02689 if (int_64bit || !(MTYPE_is_signed(imtype))) {
02690 switch (rm) {
02691 case ROUND_USER: top = TOP_cvt_l_s; break;
02692 case ROUND_NEAREST: top = TOP_round_l_s; break;
02693 case ROUND_CHOP: top = TOP_trunc_l_s; break;
02694 case ROUND_NEG_INF: top = TOP_floor_l_s; break;
02695 case ROUND_PLUS_INF: top = TOP_ceil_l_s; break;
02696 default: FmtAssert(FALSE,("Unimplemented rounding mode"));
02697 }
02698 }
02699 else {
02700 switch (rm) {
02701 case ROUND_USER: top = TOP_cvt_w_s; break;
02702 case ROUND_NEAREST: top = TOP_round_w_s; break;
02703 case ROUND_CHOP: top = TOP_trunc_w_s; break;
02704 case ROUND_NEG_INF: top = TOP_floor_w_s; break;
02705 case ROUND_PLUS_INF: top = TOP_ceil_w_s; break;
02706 default: FmtAssert(FALSE,("Unimplemented rounding mode"));
02707 }
02708 }
02709 }
02710 else if (fmtype == MTYPE_F8) {
02711 if (int_64bit || !(MTYPE_is_signed(imtype))) {
02712 switch (rm) {
02713 case ROUND_USER: top = TOP_cvt_l_d; break;
02714 case ROUND_NEAREST: top = TOP_round_l_d; break;
02715 case ROUND_CHOP: top = TOP_trunc_l_d; break;
02716 case ROUND_NEG_INF: top = TOP_floor_l_d; break;
02717 case ROUND_PLUS_INF: top = TOP_ceil_l_d; break;
02718 default: FmtAssert(FALSE,("Unimplemented rounding mode"));
02719 }
02720 }
02721 else {
02722 switch (rm) {
02723 case ROUND_USER: top = TOP_cvt_w_d; break;
02724 case ROUND_NEAREST: top = TOP_round_w_d; break;
02725 case ROUND_CHOP: top = TOP_trunc_w_d; break;
02726 case ROUND_NEG_INF: top = TOP_floor_w_d; break;
02727 case ROUND_PLUS_INF: top = TOP_ceil_w_d; break;
02728 default: FmtAssert(FALSE,("Unimplemented rounding mode"));
02729 }
02730 }
02731 }
02732 else FmtAssert(FALSE,("unsupported float size in Expand_Float_To_Int"));
02733 if (imtype == fmtype)
02734 return;
02735 TN *tmp = Build_TN_Of_Mtype (fmtype);
02736 Build_OP(top, tmp, src, ops);
02737 Build_OP(int_64bit ? TOP_dmfc1 : TOP_mfc1, dest, tmp, ops);
02738 }
02739
02740 void
02741 Expand_Float_To_Int_Cvt (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
02742 {
02743 Expand_Float_To_Int (ROUND_USER, dest, src, imtype, fmtype, ops);
02744 }
02745
02746 void
02747 Expand_Float_To_Int_Round (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
02748 {
02749 Expand_Float_To_Int (ROUND_NEAREST, dest, src, imtype, fmtype, ops);
02750 }
02751
02752 void
02753 Expand_Float_To_Int_Trunc (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
02754 {
02755 #if !defined(TARG_SL)
02756 Expand_Float_To_Int (ROUND_CHOP, dest, src, imtype, fmtype, ops);
02757 #else
02758 TN *tmp = Build_TN_Of_Mtype(MTYPE_I4);
02759 TN *tmp2 = Build_TN_Of_Mtype(MTYPE_I4);
02760 Build_OP(TOP_cfc1, tmp2, ops);
02761 Build_OP(TOP_ori, tmp, tmp2, Gen_Literal_TN(0x3, 4), ops);
02762 Build_OP(TOP_xori, tmp, tmp, Gen_Literal_TN(0x2, 4), ops);
02763 Build_OP(TOP_ctc1, tmp,ops);
02764 Build_OP(fmtype == MTYPE_F4 ? TOP_cvt_w_s : TOP_cvt_w_d, src, src, ops);
02765 Build_OP(TOP_ctc1, tmp2, ops);
02766 Build_OP(TOP_mfc1, dest, src, ops);
02767 #endif
02768 }
02769
02770
02771 void
02772 Expand_Float_To_Int_Floor (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
02773 {
02774 Expand_Float_To_Int (ROUND_NEG_INF, dest, src, imtype, fmtype, ops);
02775 }
02776
02777 void
02778 Expand_Float_To_Int_Ceil (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
02779 {
02780 Expand_Float_To_Int (ROUND_PLUS_INF, dest, src, imtype, fmtype, ops);
02781 }
02782
02783 void
02784 Expand_Float_To_Float (TN *dest, TN *src, TYPE_ID rtype, TYPE_ID desc, OPS *ops)
02785 {
02786 TOP top = (rtype == MTYPE_F8) ? TOP_cvt_d_s : TOP_cvt_s_d;
02787 Build_OP(top, dest, src, ops);
02788 }
02789
02790
02791 void
02792 Expand_Int_To_Float (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
02793 {
02794 TOP top;
02795 BOOL int_64bit = MTYPE_byte_size(imtype) == 8;
02796 TN *tmp = Build_TN_Of_Mtype(fmtype);
02797 Build_OP(int_64bit ? TOP_dmtc1 : TOP_mtc1, tmp, src, ops);
02798 if (fmtype == MTYPE_F4) {
02799
02800 top = (MTYPE_is_signed(imtype)? TOP_cvt_s_w: TOP_cvt_s_l);
02801 if (MTYPE_is_size_double(imtype))
02802 top = TOP_cvt_s_l;
02803 }
02804 else if (fmtype == MTYPE_F8) {
02805
02806 top = (MTYPE_is_signed(imtype)? TOP_cvt_d_w: TOP_cvt_d_l);
02807 if (MTYPE_is_size_double(imtype))
02808 top = TOP_cvt_d_l;
02809 }
02810 else FmtAssert(FALSE,("unsupported float size in Expand_Int_To_Float"));
02811 Build_OP(top, dest, tmp, ops);
02812 }
02813
02814
02815 static BOOL
02816 Optimize_Select (
02817 TOP cmp,
02818 TN *cond1,
02819 TN *cond2,
02820 TN *dest,
02821 TN *dest2,
02822 TN *src1,
02823 TN *src2,
02824 BOOL is_float,
02825 OPS *ops)
02826 {
02827 return FALSE;
02828 }
02829
02830 #if defined(TARG_SL)
02831
02832
02833
02834
02835 static BOOL tns_are_equals (TN *tn1, TN *tn2){
02836 if (tn_registers_identical(tn1, tn2)) {
02837 return TRUE;
02838 }
02839 else if (TN_is_constant(tn1)&&TN_is_constant(tn2)&&(TN_value(tn1)==TN_value(tn2))) {
02840 return TRUE;
02841 }
02842 return FALSE;
02843 }
02844
02845
02846
02847
02848
02849
02850
02851 extern void Exp_2inst_MC_Zero (
02852 TOP mc_op,
02853 TN *dest_tn,
02854 TN *true_tn,
02855 TN *false_tn,
02856 TN *cond_tn,
02857 TYPE_ID true_type,
02858 TYPE_ID false_type,
02859 int unsignedflag,
02860 OPS* ops )
02861 {
02862 TOP op2;
02863 TN *flag_tn = Gen_Literal_TN(unsignedflag, 4);
02864
02865 switch(mc_op) {
02866 case TOP_mc_z_ne:
02867 op2 = TOP_mc_z_eq;
02868 break;
02869 case TOP_mc_z_eq:
02870 op2 = TOP_mc_z_ne;
02871 break;
02872 case TOP_mc_z_lt:
02873 op2 = TOP_mc_z_ge;
02874 break;
02875 case TOP_mc_z_gt:
02876 op2 = TOP_mc_z_le;
02877 break;
02878 case TOP_mc_z_le:
02879 op2 = TOP_mc_z_gt;
02880 break;
02881 case TOP_mc_z_ge:
02882 op2 = TOP_mc_z_lt;
02883 break;
02884 default:
02885 FmtAssert(FALSE, ("Unknown opcode %s", mc_op));
02886 }
02887
02888 Build_OP(mc_op, dest_tn, cond_tn, true_tn, flag_tn, dest_tn, ops);
02889 Build_OP(op2, dest_tn, cond_tn, false_tn, flag_tn, dest_tn, ops);
02890
02891 if ((MTYPE_bit_size(true_type) == 64) || (MTYPE_bit_size(false_type) == 64)) {
02892
02893 TN *dest_tn_high = Get_TN_Pair(dest_tn);
02894 FmtAssert (dest_tn_high, ("Exp_2inst_MC_Zero: get dest_tn_high failed"));
02895
02896 TN *true_tn_high = Get_TN_Pair(true_tn);
02897
02898 if (true_tn_high == NULL) {
02899 DevWarn("true_tn_high is null");
02900 true_tn_high = Get_64Bit_High_TN(true_tn, true_type, ops);
02901 }
02902
02903 Build_OP(mc_op, dest_tn_high, cond_tn, true_tn_high, flag_tn, dest_tn_high, ops);
02904
02905 TN *false_tn_high = Get_TN_Pair(false_tn);
02906 if (false_tn_high == NULL) {
02907 DevWarn("false_tn_high is null");
02908 false_tn_high = Get_64Bit_High_TN(false_tn, false_type, ops);
02909 }
02910 Build_OP(op2, dest_tn_high, cond_tn, false_tn_high, flag_tn, dest_tn_high, ops);
02911 }
02912
02913 return;
02914 }
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924 static TOP Get_MC_R_TOP (OPERATOR opr, BOOL cond_eq_true= TRUE) {
02925 TOP mcr;
02926 switch (opr) {
02927 case OPR_LE:
02928 if (cond_eq_true)
02929 mcr = TOP_mc_r_le;
02930 else
02931 mcr = TOP_mc_r_gt;
02932 break;
02933 case OPR_GE:
02934 if (cond_eq_true)
02935 mcr = TOP_mc_r_ge;
02936 else
02937 mcr = TOP_mc_r_lt;
02938 break;
02939 case OPR_LT:
02940 if (cond_eq_true)
02941 mcr = TOP_mc_r_lt;
02942 else
02943 mcr = TOP_mc_r_ge;
02944 break;
02945 case OPR_GT:
02946 if (cond_eq_true)
02947 mcr = TOP_mc_r_gt;
02948 else
02949 mcr = TOP_mc_r_le;
02950 break;
02951 case OPR_EQ:
02952 if (cond_eq_true)
02953 mcr = TOP_mc_r_eq;
02954 else
02955 mcr = TOP_mc_r_ne;
02956 break;
02957 case OPR_NE:
02958 if (cond_eq_true)
02959 mcr = TOP_mc_r_ne;
02960 else
02961 mcr = TOP_mc_r_eq;
02962 break;
02963 default:
02964 FmtAssert(FALSE, ("Unknown opcode"));
02965 }
02966 return mcr;
02967 }
02968
02969
02970
02971
02972
02973
02974
02975
02976 static TOP Get_MC_ZERO_TOP(OPERATOR opr, BOOL result_eq_true = TRUE)
02977 {
02978 TOP mcz;
02979 switch (opr) {
02980 case OPR_LE:
02981 if (result_eq_true)
02982 mcz = TOP_mc_z_gt;
02983 else
02984 mcz = TOP_mc_z_le;
02985 break;
02986 case OPR_GE:
02987 if (result_eq_true)
02988 mcz = TOP_mc_z_lt;
02989 else
02990 mcz = TOP_mc_z_ge;
02991 break;
02992 case OPR_LT:
02993 if (result_eq_true)
02994 mcz = TOP_mc_z_ge;
02995 else
02996 mcz = TOP_mc_z_lt;
02997 break;
02998 case OPR_GT:
02999 if (result_eq_true)
03000 mcz = TOP_mc_z_le;
03001 else
03002 mcz = TOP_mc_z_gt;
03003 break;
03004 case OPR_EQ:
03005 if (result_eq_true)
03006 mcz = TOP_mc_z_ne;
03007 else
03008 mcz = TOP_mc_z_eq;
03009 break;
03010 case OPR_NE:
03011 if (result_eq_true)
03012 mcz = TOP_mc_z_eq;
03013 else
03014 mcz = TOP_mc_z_ne;
03015 break;
03016 default:
03017 FmtAssert(FALSE, ("Unknown opcode"));
03018 }
03019 return mcz;
03020 }
03021
03022
03023
03024
03025
03026
03027
03028
03029 static TOP Get_MC_ZC_TOP(OPERATOR opr, BOOL true_eq_zero = TRUE) {
03030 TOP mczc;
03031 switch (opr) {
03032 case OPR_LE:
03033 if (true_eq_zero)
03034 mczc = TOP_mc_zc_gt;
03035 else
03036 mczc = TOP_mc_zc_le;
03037 break;
03038 case OPR_GE:
03039 if (true_eq_zero)
03040 mczc = TOP_mc_zc_lt;
03041 else
03042 mczc = TOP_mc_zc_ge;
03043 break;
03044 case OPR_LT:
03045 if (true_eq_zero)
03046 mczc = TOP_mc_zc_ge;
03047 else
03048 mczc = TOP_mc_zc_lt;
03049 break;
03050 case OPR_GT:
03051 if (true_eq_zero)
03052 mczc = TOP_mc_zc_le;
03053 else
03054 mczc = TOP_mc_zc_gt;
03055 break;
03056 case OPR_EQ:
03057 if (true_eq_zero)
03058 mczc = TOP_mc_zc_ne;
03059 else
03060 mczc = TOP_mc_zc_eq;
03061 break;
03062 case OPR_NE:
03063 if (true_eq_zero)
03064 mczc = TOP_mc_zc_eq;
03065 else
03066 mczc = TOP_mc_zc_ne;
03067 break;
03068 default:
03069 FmtAssert(FALSE, ("Unknown opcode"));
03070 }
03071 return mczc;
03072 }
03073
03074
03075
03076
03077 void Exp_Compare(OPCODE compare,TN *p, TN *cmp_kid1, TN *cmp_kid2, OPS *ops) {
03078
03079 TYPE_ID desc = OPCODE_desc(compare);
03080 OPERATOR compare_opr = OPCODE_operator(compare);
03081
03082 switch(compare_opr) {
03083 case OPR_LT:
03084 {
03085 Expand_Int_Less(p, cmp_kid1, cmp_kid2, desc, ops);
03086 }
03087 break;
03088 case OPR_LE:
03089 {
03090 Expand_Int_Less_Equal(p, cmp_kid1, cmp_kid2, desc, ops);
03091 }
03092 break;
03093 case OPR_EQ:
03094 {
03095 Expand_Int_Equal(p, cmp_kid1, cmp_kid2, desc, ops);
03096 }
03097 break;
03098 case OPR_NE:
03099 {
03100 Expand_Int_Not_Equal(p, cmp_kid1, cmp_kid2, desc, ops);
03101 }
03102 break;
03103 case OPR_GE:
03104 {
03105 Expand_Int_Greater_Equal(p, cmp_kid1, cmp_kid2, desc, ops);
03106 }
03107 break;
03108 case OPR_GT:
03109 {
03110 Expand_Int_Greater(p, cmp_kid1, cmp_kid2, desc, ops);
03111 }
03112 break;
03113 default:
03114 FmtAssert(FALSE, ("Unknown opcode"));
03115 }
03116 }
03117
03118 static BOOL
03119 tn_is_zero (TN *tn, TYPE_ID type)
03120 {
03121 TN *tn_high = NULL;
03122 if (MTYPE_is_longlong(type) && TN_is_register(tn)) {
03123 tn_high = Get_TN_Pair(tn);
03124 FmtAssert(tn_high, ("tn_is_zero: Get tn_high fail"));
03125 }
03126 return ((TN_is_constant(tn) && TN_value(tn) ==0)
03127 || (MTYPE_is_longlong(type) && tn_registers_identical(tn, Zero_TN) && tn_registers_identical(tn_high, Zero_TN))
03128 || (!MTYPE_is_longlong(type) && tn_registers_identical(tn, Zero_TN)));
03129 }
03130
03131 static BOOL Equiv (WN* wn1, WN* wn2)
03132 {
03133 if (!WN_Equiv(wn1,wn2)) return(FALSE);
03134 for (INT kidno=0; kidno<WN_kid_count(wn1); kidno++) {
03135 if (!Equiv(WN_kid(wn1,kidno),WN_kid(wn2,kidno))) {
03136 return(FALSE);
03137 }
03138 }
03139 return(TRUE);
03140 }
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155 extern BOOL Exp_Opt_Select_And_Condition (WN *select,
03156 TN *result, TN *true_tn, TN *false_tn, TN *cmp_kid1, TN *cmp_kid2, OPS *ops)
03157 {
03158
03159 OPCODE select_opc = WN_opcode (select);
03160 TYPE_ID mtype = OPCODE_rtype(select_opc);
03161
03162 WN *compare = WN_kid0(select);
03163 WN *cmp1_wn = WN_kid0(compare);
03164 WN *cmp2_wn =WN_kid1(compare);
03165 OPCODE compare_opc = WN_opcode(compare);
03166
03167 TYPE_ID cmp1_type = WN_rtype(cmp1_wn);
03168 TYPE_ID cmp2_type = WN_rtype(cmp2_wn);
03169
03170 INT unsignedflag = MTYPE_signed(OPCODE_desc(compare_opc)) ? 0 : 1;
03171 TN *flag_tn = Gen_Literal_TN(unsignedflag, 4);
03172 OPERATOR compare_opr = OPCODE_operator(compare_opc);
03173
03174 WN *true_wn = WN_kid1(select);
03175 WN *false_wn = WN_kid2(select);
03176 TYPE_ID true_type = WN_rtype(true_wn);
03177 TYPE_ID false_type = WN_rtype(false_wn);
03178
03179 OPS new_ops;
03180 OPS_Init(&new_ops);
03181
03182 Is_True ((select_opc == OPC_U4SELECT || select_opc == OPC_I4SELECT
03183 || select_opc == OPC_U8SELECT || select_opc == OPC_I8SELECT
03184 || select_opc == OPC_F4SELECT || select_opc == OPC_F8SELECT),
03185 ("Handle_Select:: Unexpected select operator, %d", select_opc)) ;
03186
03187
03188
03189
03190
03191 if (tns_are_equals (true_tn, false_tn)) {
03192
03193 Expand_Copy(result, true_tn, mtype, &new_ops);
03194 goto DONE;
03195 }
03196
03197
03198
03199
03200 if (WN_operator(true_wn) == OPR_ADD && (WN_kid_count(false_wn) == 1) &&
03201 ((WN_operator(WN_kid0(true_wn)) == OPR_INTCONST &&
03202 WN_const_val(WN_kid0(true_wn)) == 1 &&
03203 WN_Equiv(WN_kid1(true_wn), false_wn))
03204
03205 || (WN_operator(WN_kid1(true_wn)) == OPR_INTCONST &&
03206 WN_const_val(WN_kid1(true_wn)) == 1 &&
03207 Equiv(WN_kid0(true_wn), false_wn)) ))
03208
03209 {
03210 TN *tmp = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03211 Exp_Compare(WN_opcode(compare), tmp, cmp_kid1, cmp_kid2, &new_ops);
03212 Expand_Add(result, false_tn, tmp, mtype, &new_ops);
03213
03214 DevWarn("Conditional move::Exp_Opt_Select_And_Condition (setlt) 4 instruction ");
03215 goto DONE;
03216 }
03217
03218 if (select_opc == OPC_U4SELECT || select_opc == OPC_I4SELECT || select_opc == OPC_F4SELECT) {
03219
03220 if ((Equiv(true_wn, cmp1_wn) && Equiv(false_wn, cmp2_wn))
03221 || (Equiv(true_wn, cmp2_wn) && Equiv(false_wn, cmp1_wn))) {
03222
03223
03224
03225
03226
03227
03228 BOOL true_tn_eq_cmp1 = (WN_Equiv(true_wn, cmp1_wn) && WN_Equiv(false_wn, cmp2_wn));
03229 TOP mcr=Get_MC_R_TOP(compare_opr, true_tn_eq_cmp1);
03230 if (true_tn_eq_cmp1)
03231 Build_OP(mcr, result, true_tn, false_tn, flag_tn, &new_ops);
03232 else
03233 Build_OP(mcr, result, false_tn, true_tn, flag_tn, &new_ops);
03234 goto DONE;
03235 }
03236
03237 if ((tns_are_equals (cmp_kid1, true_tn) && tns_are_equals(cmp_kid2, false_tn))
03238 ||(tns_are_equals (cmp_kid1, false_tn) && tns_are_equals(cmp_kid2, true_tn))) {
03239
03240
03241
03242
03243
03244 BOOL kid1_eq_truetn = tns_are_equals (cmp_kid1, true_tn) && tns_are_equals(cmp_kid2, false_tn);
03245 TOP mcr=Get_MC_R_TOP(compare_opr, kid1_eq_truetn);
03246 Build_OP(mcr, result, cmp_kid1, cmp_kid2, flag_tn, &new_ops);
03247 goto DONE;
03248 }
03249
03250 if (!MTYPE_is_longlong(cmp1_type) && tn_is_zero(cmp_kid2, cmp2_type)) {
03251
03252 if (tn_is_zero(false_tn, false_type) || tn_is_zero(true_tn, true_type)){
03253
03254
03255
03256
03257 BOOL true_tn_is_zero = tn_is_zero(true_tn, true_type);
03258 TN *src_tn = true_tn_is_zero ? false_tn: true_tn;
03259 TOP mczc = Get_MC_ZC_TOP(compare_opr, true_tn_is_zero);
03260 Build_OP(mczc, result, cmp_kid1, src_tn, flag_tn, &new_ops);
03261 } else if (tns_are_equals(result, true_tn) || tns_are_equals(result, false_tn)) {
03262
03263
03264
03265
03266 BOOL result_eq_true = tns_are_equals(result, true_tn);
03267 TN *src_tn = result_eq_true ? false_tn: true_tn;
03268 TOP mcz = Get_MC_ZERO_TOP(compare_opr, result_eq_true);
03269 Build_OP(mcz, result, cmp_kid1, src_tn, flag_tn, Zero_TN, &new_ops);
03270 Set_OP_cond_def_kind(OPS_last(&new_ops), OP_ALWAYS_COND_DEF);
03271 } else {
03272
03273
03274 TOP mcz = Get_MC_ZERO_TOP(compare_opr, FALSE);
03275 Exp_2inst_MC_Zero(mcz, result, true_tn, false_tn, cmp_kid1, true_type, false_type, unsignedflag, &new_ops);
03276 DevWarn("Conditional move::Exp_Opt_Select_And_Condition (mc_zero) 2 instruction ");
03277
03278 }
03279 } else {
03280
03281 TN *cond_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03282 Exp_Compare(WN_opcode(compare), cond_tn, cmp_kid1, cmp_kid2, &new_ops);
03283 if (tn_is_zero(false_tn, false_type) || tn_is_zero(true_tn, true_type)){
03284
03285
03286
03287
03288 BOOL true_tn_is_zero = tn_is_zero(true_tn, true_type);
03289 TN *src_tn = true_tn_is_zero ? false_tn: true_tn;
03290 TOP mczc = true_tn_is_zero? TOP_mc_zc_eq: TOP_mc_zc_ne;
03291 Build_OP(mczc, result, cond_tn, src_tn, flag_tn, &new_ops);
03292 } else if (tns_are_equals(result, true_tn) || tns_are_equals(result, false_tn)) {
03293
03294
03295
03296
03297 BOOL result_eq_true = tns_are_equals(result, true_tn);
03298 TN *src_tn = result_eq_true ? false_tn: true_tn;
03299 TOP mcz = result_eq_true ? TOP_mc_z_eq : TOP_mc_z_ne ;
03300 Build_OP(mcz, result, cond_tn, src_tn, flag_tn, Zero_TN, &new_ops);
03301 Set_OP_cond_def_kind(OPS_last(&new_ops), OP_ALWAYS_COND_DEF);
03302 }
03303 else {
03304
03305 TOP mcz = TOP_mc_z_ne;
03306 Exp_2inst_MC_Zero(mcz, result, true_tn, false_tn, cond_tn, true_type, false_type, unsignedflag, &new_ops);
03307 DevWarn("Conditional move::Exp_Opt_Select_And_Condition (mc_zero) 2 instruction ");
03308 }
03309 }
03310 }else if (select_opc == OPC_U8SELECT || select_opc == OPC_I8SELECT || select_opc == OPC_F8SELECT){
03311 TN *true_tn_high = Get_TN_Pair(true_tn);
03312 TN *false_tn_high = Get_TN_Pair(false_tn);
03313 TN *result_high = Get_TN_Pair(result);
03314
03315 FmtAssert(true_tn_high, ("Exp_Opt_Select_And_Condition: Get true_tn_high fail"));
03316 FmtAssert(false_tn_high, ("Exp_Opt_Select_And_Condition: Get false_tn_high fail"));
03317
03318 if (tn_is_zero(cmp_kid2, cmp2_type) && !MTYPE_is_longlong(cmp1_type)) {
03319
03320 if (tn_is_zero(false_tn, false_type) || tn_is_zero(true_tn, true_type)) {
03321
03322
03323
03324
03325 BOOL true_tn_is_zero = tn_is_zero(true_tn, true_type);
03326 TN *src_tn = true_tn_is_zero ? false_tn: true_tn;
03327 TN *src_tn_high = true_tn_is_zero ? false_tn_high: true_tn_high;
03328 TOP mczc = Get_MC_ZC_TOP(compare_opr, true_tn_is_zero);
03329 Build_OP(mczc, result, cmp_kid1, src_tn, flag_tn, &new_ops);
03330 Build_OP(mczc, result_high, cmp_kid1, src_tn_high, flag_tn, &new_ops);
03331
03332 } else if ((tns_are_equals(result, true_tn) && tns_are_equals(result_high, true_tn_high))
03333 || (tns_are_equals(result, false_tn) && tns_are_equals(result_high, false_tn_high))) {
03334
03335
03336
03337
03338 BOOL result_eq_true = tns_are_equals(result, true_tn) && tns_are_equals(result_high, true_tn_high);
03339 TN *src_tn = result_eq_true ? false_tn: true_tn;
03340 TN *src_tn_high = result_eq_true ? false_tn_high: true_tn_high;
03341 TOP mcz = Get_MC_ZERO_TOP(compare_opr, result_eq_true);
03342 Build_OP(mcz, result, cmp_kid1, src_tn, flag_tn, Zero_TN, &new_ops);
03343 Set_OP_cond_def_kind(OPS_last(&new_ops), OP_ALWAYS_COND_DEF);
03344 Build_OP(mcz, result_high, cmp_kid1, src_tn_high, flag_tn, Zero_TN, &new_ops);
03345 Set_OP_cond_def_kind(OPS_last(&new_ops), OP_ALWAYS_COND_DEF);
03346 } else {
03347 TOP mcz = Get_MC_ZERO_TOP(compare_opr, FALSE);
03348 Exp_2inst_MC_Zero(mcz, result, true_tn, false_tn, cmp_kid1, true_type, false_type, unsignedflag, &new_ops);
03349 DevWarn("Conditional move::Exp_Opt_Select_And_Condition (mc_zero) 4 instruction ");
03350 }
03351 } else {
03352
03353 TN *cond_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03354 Exp_Compare(WN_opcode(compare), cond_tn, cmp_kid1, cmp_kid2, &new_ops);
03355
03356 if (tn_is_zero(false_tn, false_type) || tn_is_zero(true_tn, true_type)) {
03357
03358
03359
03360
03361 BOOL true_tn_is_zero = tn_is_zero(true_tn, true_type);
03362 TN *src_tn = true_tn_is_zero? false_tn: true_tn;
03363 TN *src_tn_high = true_tn_is_zero? false_tn_high: true_tn_high;
03364 TOP mczc = true_tn_is_zero ? TOP_mc_zc_eq : TOP_mc_zc_ne;
03365 Build_OP(mczc, result, cond_tn, src_tn, flag_tn, &new_ops);
03366 Build_OP(mczc, result_high, cond_tn, src_tn_high, flag_tn, &new_ops);
03367
03368 } else if ((tns_are_equals(result, true_tn) && tns_are_equals(result_high, true_tn_high))
03369 || (tns_are_equals(result, false_tn) && tns_are_equals(result_high, false_tn_high))) {
03370
03371
03372
03373
03374 BOOL result_eq_true = tns_are_equals(result, true_tn) && tns_are_equals(result_high, true_tn_high);
03375 TN *src_tn = result_eq_true ? false_tn: true_tn;
03376 TN *src_tn_high = result_eq_true ? false_tn_high: true_tn_high;
03377 TOP mcz = result_eq_true ? TOP_mc_z_eq : TOP_mc_z_ne;
03378 Build_OP(mcz, result, cond_tn, src_tn, flag_tn, Zero_TN, &new_ops);
03379 Set_OP_cond_def_kind(OPS_last(&new_ops), OP_ALWAYS_COND_DEF);
03380 Build_OP(mcz, result_high, cond_tn, src_tn_high, flag_tn, Zero_TN, &new_ops);
03381 Set_OP_cond_def_kind(OPS_last(&new_ops), OP_ALWAYS_COND_DEF);
03382 } else {
03383
03384
03385 TOP mcz = TOP_mc_z_ne;
03386 Exp_2inst_MC_Zero(mcz, result, true_tn, false_tn, cond_tn, true_type, false_type, TRUE, &new_ops);
03387 DevWarn("Conditional move::Exp_Select_And_Condition (mc_zero) 2 instruction ");
03388 }
03389 }
03390 }
03391
03392
03393 DONE:
03394 if (OPS_length(&new_ops) == 0) {
03395 return FALSE;
03396 }
03397 else {
03398 OPS_Append_Ops(ops, &new_ops);
03399 return TRUE;
03400 }
03401
03402 }
03403
03404 #endif // TARG_SL
03405
03406
03407 static void
03408 Expand_Compare_And_Select (
03409 TOP cmp,
03410 TN *cond1,
03411 TN *cond2,
03412 TN *dest,
03413 TN *opposite_dest,
03414 TN *true_tn,
03415 TN *false_tn,
03416 BOOL is_float,
03417 OPS *ops)
03418 { FmtAssert(FALSE,("Unimplemented")); }
03419
03420
03421 #ifdef TARG_SL
03422 void
03423 Expand_Select (
03424 TN *dest_tn,
03425 TN *cond_tn,
03426 TN *true_tn,
03427 TN *false_tn,
03428 TYPE_ID mtype,
03429 BOOL float_cond,
03430 OPS *ops)
03431 {
03432 const BOOL is_float = MTYPE_is_float(mtype);
03433
03434 Is_True((mtype == MTYPE_U4 || mtype==MTYPE_I4 || mtype == MTYPE_U8 ||
03435 mtype == MTYPE_I8) , ("mtype must be MTYPE_I4/U4/I8/U8\n" ));
03436
03437 if (TN_register_class(cond_tn) == ISA_REGISTER_CLASS_integer) {
03438
03439 if (MTYPE_bit_size(mtype) == 32) {
03440 TN *flag_tn = Gen_Literal_TN(1, 4);
03441 if (tns_are_equals(true_tn, false_tn)) {
03442 Build_OP(TOP_addu, dest_tn, true_tn, Zero_TN, ops);
03443 DevWarn("Conditional move:: Expand_Select(1 instructions -copy) ");
03444 } else if (tns_are_equals(Zero_TN, true_tn)) {
03445 Build_OP(TOP_mc_zc_eq, dest_tn, cond_tn, false_tn, flag_tn, ops);
03446 } else if (tns_are_equals(Zero_TN, false_tn)) {
03447 Build_OP(TOP_mc_zc_ne, dest_tn, cond_tn, true_tn, flag_tn, ops);
03448 } else if (tns_are_equals(dest_tn, false_tn)) {
03449 Build_OP(TOP_mc_z_ne, dest_tn, cond_tn, true_tn, flag_tn, Zero_TN, ops);
03450 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03451 } else if (tns_are_equals(dest_tn, true_tn)) {
03452 Build_OP(TOP_mc_z_eq, dest_tn, cond_tn, false_tn, flag_tn, Zero_TN, ops);
03453 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03454 } else {
03455 Exp_2inst_MC_Zero (TOP_mc_z_ne, dest_tn, true_tn, false_tn, cond_tn, mtype, mtype, TRUE, ops);
03456 DevWarn("Conditional move:: Expand_Select(2 instructions) ");
03457 }
03458
03459 } else if (MTYPE_bit_size(mtype) == 64) {
03460 TN *true_tn_high = Get_TN_Pair(true_tn);
03461 TN *false_tn_high = Get_TN_Pair(false_tn);
03462 TN *dest_tn_high = Get_TN_Pair(dest_tn);
03463
03464 FmtAssert(true_tn_high, ("Exp_Opt_Select_And_Condition: Get true_tn_high fail"));
03465 FmtAssert(false_tn_high, ("Exp_Opt_Select_And_Condition: Get false_tn_high fail"));
03466 if (tn_is_zero(false_tn, mtype) || tn_is_zero(true_tn, mtype)) {
03467
03468
03469
03470
03471
03472 BOOL true_tn_is_zero = tn_is_zero(true_tn, mtype);
03473 TN *src_tn = true_tn_is_zero? false_tn: true_tn;
03474 TN *src_tn_high = true_tn_is_zero? false_tn_high: true_tn_high;
03475 TOP mczc = true_tn_is_zero ? TOP_mc_zc_eq : TOP_mc_zc_ne;
03476
03477 Build_OP(mczc, dest_tn, cond_tn, src_tn, Gen_Literal_TN(1, 4), ops);
03478 Build_OP(mczc, dest_tn_high, cond_tn, src_tn_high, Gen_Literal_TN(1, 4), ops);
03479
03480 } else if ((tns_are_equals(dest_tn, true_tn) && tns_are_equals(dest_tn_high, true_tn_high))
03481 || (tns_are_equals(dest_tn, false_tn) && tns_are_equals(dest_tn_high, false_tn_high))) {
03482
03483
03484
03485 BOOL dest_tn_eq_true = tns_are_equals(dest_tn, true_tn) && tns_are_equals(dest_tn_high, true_tn_high);
03486 TN *src_tn = dest_tn_eq_true ? false_tn: true_tn;
03487 TN *src_tn_high = dest_tn_eq_true ? false_tn_high: true_tn_high;
03488 TOP mcz = dest_tn_eq_true ? TOP_mc_z_eq : TOP_mc_z_ne;
03489 Build_OP(mcz, dest_tn, cond_tn, src_tn, Gen_Literal_TN(1, 4), Zero_TN, ops);
03490 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03491 Build_OP(mcz, dest_tn_high, cond_tn, src_tn_high, Gen_Literal_TN(1, 4), Zero_TN, ops);
03492 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03493 } else {
03494 Exp_2inst_MC_Zero(TOP_mc_z_ne, dest_tn, true_tn, false_tn, cond_tn, mtype, mtype, TRUE, ops);
03495 DevWarn("Conditional move::Exp_Select_And_Condition (mc_zero) 2 instruction ");
03496 }
03497 } else {
03498 FmtAssert(FALSE, ("Expand_Select: Unexpected mtype"));
03499 }
03500 } else if (TN_register_class(cond_tn) == ISA_REGISTER_CLASS_float) {
03501 FmtAssert(FALSE, ("Expand_Select: cond_tn type is float which isnot expected"));
03502 } else {
03503 FmtAssert(FALSE, ("UNIMPLEMENTED"));
03504 }
03505 }
03506 #else
03507
03508 void
03509 Expand_Select (
03510 TN *dest_tn,
03511 TN *cond_tn,
03512 TN *true_tn,
03513 TN *false_tn,
03514 TYPE_ID mtype,
03515 BOOL float_cond,
03516 OPS *ops)
03517 {
03518 const BOOL is_float = MTYPE_is_float(mtype);
03519 if (TN_register_class(cond_tn) == ISA_REGISTER_CLASS_fcc) {
03520 if (is_float) {
03521 Build_OP(MTYPE_is_size_double(mtype)?TOP_movt_d:TOP_movt_s,
03522 dest_tn, true_tn, cond_tn, ops);
03523 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03524 Build_OP(MTYPE_is_size_double(mtype)?TOP_movf_d:TOP_movf_s,
03525 dest_tn, false_tn, cond_tn, ops);
03526 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03527 } else {
03528 Build_OP(TOP_movt, dest_tn, true_tn, cond_tn, ops);
03529 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03530 Build_OP(TOP_movf, dest_tn, false_tn, cond_tn, ops);
03531 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03532 }
03533 } else if (TN_register_class(cond_tn) == ISA_REGISTER_CLASS_integer) {
03534 if (is_float) {
03535 Build_OP(MTYPE_is_size_double(mtype)?TOP_movn_d:TOP_movn_s,
03536 dest_tn, true_tn, cond_tn, ops);
03537 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03538 Build_OP(MTYPE_is_size_double(mtype)?TOP_movz_d:TOP_movz_s,
03539 dest_tn, false_tn, cond_tn, ops);
03540 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03541 } else {
03542 Build_OP(TOP_movn, dest_tn, true_tn, cond_tn, ops);
03543 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03544 Build_OP(TOP_movz, dest_tn, false_tn, cond_tn, ops);
03545 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03546 }
03547 } else if (TN_register_class(cond_tn) == ISA_REGISTER_CLASS_float) {
03548 TN *tmp_tn = Gen_Typed_Register_TN(MTYPE_I4, 4);
03549 Build_OP(TOP_mfc1, tmp_tn, cond_tn, ops);
03550 if (is_float) {
03551 Build_OP(MTYPE_is_size_double(mtype)?TOP_movn_d:TOP_movn_s,
03552 dest_tn, true_tn, tmp_tn, ops);
03553 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03554 Build_OP(MTYPE_is_size_double(mtype)?TOP_movz_d:TOP_movz_s,
03555 dest_tn, false_tn, tmp_tn, ops);
03556 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03557 } else {
03558 Build_OP(TOP_movn, dest_tn, true_tn, tmp_tn, ops);
03559 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03560 Build_OP(TOP_movz, dest_tn, false_tn, tmp_tn, ops);
03561 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03562 }
03563 } else {
03564 FmtAssert(FALSE, ("UNIMPLEMENTED"));
03565 }
03566 }
03567 #endif
03568
03569 #ifdef TARG_SL
03570 void
03571 Expand_Min (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
03572 {
03573 FmtAssert(!MTYPE_is_float(mtype), ("Expand_Min: Unexpected type : %d", mtype));
03574
03575 if (mtype == MTYPE_U4 || mtype == MTYPE_I4) {
03576
03577 int unsignedflag = (mtype == MTYPE_U4) ? 1 :0;
03578 Build_OP(TOP_mc_r_le, dest, src1, src2, Gen_Literal_TN(unsignedflag, 4), ops);
03579 DevWarn("Conditional move:: Expand_Min(1 instruction) ");
03580
03581 }
03582 else if (mtype == MTYPE_U8 || mtype == MTYPE_I8) {
03583 TN *cond_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03584 Expand_Int_Compare(OPR_LE, cond_tn, src1, src2, mtype, ops);
03585 Exp_2inst_MC_Zero(TOP_mc_z_ne, dest, src1, src2, cond_tn, mtype, mtype, TRUE, ops);
03586 DevWarn("Conditional move:: Expand_Min(7 instruction) ");
03587 }
03588 else {
03589 Is_True(FALSE, ("Expand_Min:: mtype must be U4 or I4 or U8 or I8"));
03590 }
03591 }
03592 #else
03593 void
03594 Expand_Min (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
03595 {
03596 BOOL is_signed = MTYPE_is_signed(mtype);
03597 if (!MTYPE_is_float(mtype)) {
03598 TN *tmp_tn = Gen_Typed_Register_TN(MTYPE_I4, 4);
03599 if (src1 == dest) {
03600 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src1, src2, ops);
03601 Build_OP(TOP_movz, dest, src2, tmp_tn, ops);
03602 }
03603 else if (src2 == dest) {
03604 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src2, src1, ops);
03605 Build_OP(TOP_movz, dest, src1, tmp_tn, ops);
03606 }
03607 else {
03608 Build_OP(TOP_or, dest, src1, Zero_TN, ops);
03609 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src1, src2, ops);
03610 Build_OP(TOP_movz, dest, src2, tmp_tn, ops);
03611 }
03612 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03613 } else {
03614 TN *tmp_fcc = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 1);
03615 if (src1 == dest) {
03616 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
03617 tmp_fcc, src2, src1, ops);
03618 Build_OP(MTYPE_is_size_double(mtype)? TOP_movt_d: TOP_movt_s,
03619 dest, src2, tmp_fcc, ops);
03620 }
03621 else if (src2 == dest) {
03622 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
03623 tmp_fcc, src1, src2, ops);
03624 Build_OP(MTYPE_is_size_double(mtype)? TOP_movt_d: TOP_movt_s,
03625 dest, src1, tmp_fcc, ops);
03626 }
03627 else {
03628 Build_OP(MTYPE_is_size_double(mtype)? TOP_mov_d: TOP_mov_s,
03629 dest, src2, ops);
03630 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
03631 tmp_fcc, src1, src2, ops);
03632 Build_OP(MTYPE_is_size_double(mtype)? TOP_movt_d: TOP_movt_s,
03633 dest, src1, tmp_fcc, ops);
03634 }
03635 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03636 }
03637 }
03638 #endif
03639
03640 #ifdef TARG_SL
03641 void
03642 Expand_Max (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
03643 {
03644 FmtAssert(!MTYPE_is_float(mtype), ("Expand_Max: mtype must be interger"));
03645
03646 if (mtype == MTYPE_U4 || mtype == MTYPE_I4) {
03647
03648 int unsignedflag = (mtype == MTYPE_U4) ? 1 :0;
03649 Build_OP(TOP_mc_r_ge, dest, src1, src2, Gen_Literal_TN(unsignedflag, 4), ops);
03650 DevWarn("Conditional move:: Expand_Max(1 instruction) ");
03651 } else if (mtype == MTYPE_U8 || mtype == MTYPE_I8) {
03652
03653 TN *cond_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03654 Expand_Int_Compare(OPR_GE, cond_tn, src1, src2, mtype, ops);
03655 Exp_2inst_MC_Zero(TOP_mc_z_ne, dest, src1, src2, cond_tn, mtype, mtype, TRUE, ops);
03656
03657 DevWarn("Conditional move:: Expand_Max(7 instruction) ");
03658 } else {
03659 Is_True(FALSE, ("Expand_Max:: mtype must be U4 or I4 or U8 or I8"));
03660 }
03661 }
03662 #else
03663 void
03664 Expand_Max (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
03665 {
03666 BOOL is_signed = MTYPE_is_signed(mtype);
03667 if (!MTYPE_is_float(mtype)) {
03668 TN *tmp_tn = Gen_Typed_Register_TN(MTYPE_I4, 4);
03669 if (src1 == dest) {
03670 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src2, src1, ops);
03671 Build_OP(TOP_movz, dest, src2, tmp_tn, ops);
03672 }
03673 else if (src2 == dest) {
03674 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src1, src2, ops);
03675 Build_OP(TOP_movz, dest, src1, tmp_tn, ops);
03676 }
03677 else {
03678 Build_OP(TOP_or, dest, src2, Zero_TN, ops);
03679 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src1, src2, ops);
03680 Build_OP(TOP_movz, dest, src1, tmp_tn, ops);
03681 }
03682 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03683 } else {
03684 TN *tmp_fcc = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 1);
03685 if (src1 == dest) {
03686 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
03687 tmp_fcc, src1, src2, ops);
03688 Build_OP(MTYPE_is_size_double(mtype)? TOP_movt_d: TOP_movt_s,
03689 dest, src2, tmp_fcc, ops);
03690 }
03691 else if (src2 == dest) {
03692 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
03693 tmp_fcc, src2, src1, ops);
03694 Build_OP(MTYPE_is_size_double(mtype)? TOP_movt_d: TOP_movt_s,
03695 dest, src1, tmp_fcc, ops);
03696 }
03697 else {
03698 Build_OP(MTYPE_is_size_double(mtype)? TOP_mov_d: TOP_mov_s,
03699 dest, src1, ops);
03700 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
03701 tmp_fcc, src1, src2, ops);
03702 Build_OP(MTYPE_is_size_double(mtype)? TOP_movt_d: TOP_movt_s,
03703 dest, src2, tmp_fcc, ops);
03704 }
03705 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03706 }
03707 }
03708 #endif
03709
03710 #ifdef TARG_SL
03711 void
03712 Expand_MinMax (TN *dest, TN *dest2, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
03713 {
03714 FmtAssert(!MTYPE_is_float(mtype), ("Expand_MinMax: mtype must be interger"));
03715
03716 if (mtype == MTYPE_U4 || mtype == MTYPE_I4) {
03717
03718 int unsignedflag = (mtype == MTYPE_U4) ? 1 :0;
03719 TN *flag_tn = Gen_Literal_TN(unsignedflag, 4);
03720 Build_OP (TOP_mc_r_ge, dest, src1, src2, flag_tn, ops);
03721 Build_OP (TOP_mc_r_le, dest2, src1, src2, flag_tn, ops);
03722 DevWarn("Conditional move:: Expand_MinMax() ");
03723
03724 } else if (mtype == MTYPE_U8 || mtype == MTYPE_I8) {
03725 TN *cond_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03726 Expand_Int_Compare(OPR_GE, cond_tn, src1, src2, mtype, ops);
03727 Exp_2inst_MC_Zero(TOP_mc_z_ne, dest, src1, src2, cond_tn, mtype, mtype, TRUE, ops);
03728 Exp_2inst_MC_Zero(TOP_mc_z_eq, dest2, src1, src2, cond_tn, mtype, mtype, TRUE, ops);
03729 DevWarn("Conditional move:: Expand_Min(7 instruction) ");
03730 } else {
03731 Is_True(FALSE, ("Expand_MinMax:: mtype must be U4 or I4 or U8 or I8"));
03732 }
03733 }
03734 #else
03735 void
03736 Expand_MinMax (TN *dest, TN *dest2, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
03737 {
03738 BOOL is_signed = MTYPE_is_signed(mtype);
03739 FmtAssert(dest != src1 && dest2 != src1 && dest != src2 && dest2 != src2,
03740 ("Expand_MinMax: dest TN cannot be also src TN"));
03741 if (!MTYPE_is_float(mtype)) {
03742 TN *tmp_tn = Gen_Typed_Register_TN(MTYPE_I4, 4);
03743 Build_OP(TOP_or, dest, src1, Zero_TN, ops);
03744 Build_OP(TOP_or, dest2, src2, Zero_TN, ops);
03745 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src1, src2, ops);
03746 Build_OP(TOP_movz, dest, src2, tmp_tn, ops);
03747 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03748 Build_OP(TOP_movz, dest2, src1, tmp_tn, ops);
03749 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03750 } else {
03751 TN *tmp_fcc = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 1);
03752 Build_OP(MTYPE_is_size_double(mtype)? TOP_mov_d: TOP_mov_s,
03753 dest, src1, ops);
03754 Build_OP(MTYPE_is_size_double(mtype)? TOP_mov_d: TOP_mov_s,
03755 dest2, src2, ops);
03756 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
03757 tmp_fcc, src1, src2, ops);
03758 Build_OP(MTYPE_is_size_double(mtype)? TOP_movf_d: TOP_movf_s,
03759 dest, src2, tmp_fcc, ops);
03760 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03761 Build_OP(MTYPE_is_size_double(mtype)? TOP_movf_d: TOP_movf_s,
03762 dest2, src1, tmp_fcc, ops);
03763 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
03764 }
03765 }
03766 #endif
03767
03768
03769 extern BOOL
03770 Check_Select_Expansion (OPCODE compare)
03771 {
03772
03773
03774
03775
03776 return FALSE;
03777 }
03778
03779 #if defined(TARG_SL)
03780 extern void
03781 Exp_Select_And_Condition (
03782 WN *wn_select,
03783 OPCODE select, TN *result, TN *true_tn, TN *false_tn,
03784 OPCODE compare, TN *cmp_kid1, TN *cmp_kid2, VARIANT variant, OPS *ops)
03785 {
03786 TOP cmp1, cmp2;
03787
03788 if (Trace_Exp) {
03789 fprintf(TFile, "expand %s: ", OPCODE_name(select));
03790 if (result) Print_TN(result,FALSE);
03791 fprintf(TFile, " :- (");
03792 if (cmp_kid1) Print_TN(cmp_kid1,FALSE);
03793 fprintf(TFile, " ");
03794 fprintf(TFile, OPCODE_name(compare));
03795 fprintf(TFile, " ");
03796 if (cmp_kid2) Print_TN(cmp_kid2,FALSE);
03797 fprintf(TFile, ") ? ");
03798 if (true_tn) Print_TN(true_tn,FALSE);
03799 fprintf(TFile, " : ");
03800 if (false_tn) Print_TN(false_tn,FALSE);
03801 fprintf(TFile, " ");
03802 if (variant) fprintf(TFile, "(0x%llx)", (INT64)variant);
03803 fprintf(TFile, "\n");
03804 }
03805
03806 TYPE_ID desc = OPCODE_desc(compare);
03807 OPERATOR compare_opr = OPCODE_operator(compare);
03808 TN *p = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03809
03810 TYPE_ID true_type = WN_rtype(WN_kid1(wn_select));
03811 TYPE_ID false_type = WN_rtype(WN_kid2(wn_select));
03812
03813 OPS new_ops;
03814 OPS_Init(&new_ops);
03815
03816 Is_True(MTYPE_is_float(desc)==FALSE, ("Exp_Select_And_Condition: OPCODE_desc(compare) cannot be float typed"));
03817 Is_True(select == OPC_U4SELECT || select == OPC_I4SELECT
03818 || select == OPC_U8SELECT || select == OPC_I8SELECT
03819 || select == OPC_F4SELECT || select == OPC_F8SELECT,
03820 ("Exp_Select_And_Condition:: select opr must be U4/I4/I8/U8/F4/F8 SELECT"));
03821
03822
03823 Exp_Compare(compare,p, cmp_kid1, cmp_kid2, &new_ops);
03824 Exp_2inst_MC_Zero (TOP_mc_z_ne, result, true_tn, false_tn, p, true_type, false_type, TRUE, &new_ops);
03825 DevWarn("Conditional move:: Exp_Select_And_Condition (2 instructions) ");
03826
03827 if (Trace_Exp) {
03828 OP *op;
03829 FOR_ALL_OPS_OPs (&new_ops, op) {
03830 fprintf(TFile, " into "); Print_OP (op);
03831 }
03832 }
03833 OPS_Append_Ops(ops, &new_ops);
03834 }
03835
03836 #else
03837 extern void
03838 Exp_Select_And_Condition (
03839 OPCODE select, TN *result, TN *true_tn, TN *false_tn,
03840 OPCODE compare, TN *cmp_kid1, TN *cmp_kid2, VARIANT variant, OPS *ops)
03841 {
03842 TOP cmp1, cmp2;
03843
03844 if (Trace_Exp) {
03845 fprintf(TFile, "expand %s: ", OPCODE_name(select));
03846 if (result) Print_TN(result,FALSE);
03847 fprintf(TFile, " :- (");
03848 if (cmp_kid1) Print_TN(cmp_kid1,FALSE);
03849 fprintf(TFile, " ");
03850 fprintf(TFile, OPCODE_name(compare));
03851 fprintf(TFile, " ");
03852 if (cmp_kid2) Print_TN(cmp_kid2,FALSE);
03853 fprintf(TFile, ") ? ");
03854 if (true_tn) Print_TN(true_tn,FALSE);
03855 fprintf(TFile, " : ");
03856 if (false_tn) Print_TN(false_tn,FALSE);
03857 fprintf(TFile, " ");
03858 if (variant) fprintf(TFile, "(0x%llx)", (INT64)variant);
03859 fprintf(TFile, "\n");
03860 }
03861
03862 TYPE_ID desc = OPCODE_desc(compare);
03863 OPERATOR compare_opr = OPCODE_operator(compare);
03864 TN *p;
03865 OPS new_ops;
03866 OPS_Init(&new_ops);
03867 if (MTYPE_is_float(desc))
03868 p = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 1);
03869 else p = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03870
03871 if (compare_opr == OPR_NE) {
03872 TN *tmp = true_tn;
03873 true_tn = false_tn;
03874 false_tn = tmp;
03875 compare_opr = OPR_EQ;
03876 }
03877
03878 switch(compare_opr) {
03879 case OPR_LT:
03880 if (MTYPE_is_float(desc))
03881 Expand_Float_Less (p, cmp_kid1, cmp_kid2, variant, desc, &new_ops);
03882 else
03883 Expand_Int_Less (p, cmp_kid1, cmp_kid2, desc, &new_ops);
03884 break;
03885 case OPR_LE:
03886 if (MTYPE_is_float(desc))
03887 Expand_Float_Less_Equal (p, cmp_kid1, cmp_kid2, variant, desc, &new_ops);
03888 else
03889 Expand_Int_Less_Equal (p, cmp_kid1, cmp_kid2, desc, &new_ops);
03890 break;
03891 case OPR_EQ:
03892 if (MTYPE_is_float(desc))
03893 Expand_Float_Equal (p, cmp_kid1, cmp_kid2, variant, desc, &new_ops);
03894 else if (desc == MTYPE_B)
03895 Expand_Bool_Equal (p, cmp_kid1, cmp_kid2, &new_ops);
03896 else
03897 Expand_Int_Equal (p, cmp_kid1, cmp_kid2, desc, &new_ops);
03898 break;
03899 #if 0 // this case avoided by above transformation
03900 case OPR_NE:
03901 if (MTYPE_is_float(desc))
03902 Expand_Float_Not_Equal (p, cmp_kid1, cmp_kid2, variant, desc, &new_ops);
03903 else if (desc == MTYPE_B)
03904 Expand_Bool_Not_Equal (p, cmp_kid1, cmp_kid2, &new_ops);
03905 else
03906 Expand_Int_Not_Equal (p, cmp_kid1, cmp_kid2, desc, &new_ops);
03907 break;
03908 #endif
03909 case OPR_GE:
03910 if (MTYPE_is_float(desc))
03911 Expand_Float_Greater_Equal (p, cmp_kid1, cmp_kid2, variant, desc, &new_ops);
03912 else
03913 Expand_Int_Greater_Equal (p, cmp_kid1, cmp_kid2, desc, &new_ops);
03914 break;
03915 case OPR_GT:
03916 if (MTYPE_is_float(desc))
03917 Expand_Float_Greater (p, cmp_kid1, cmp_kid2, variant, desc, &new_ops);
03918 else
03919 Expand_Int_Greater (p, cmp_kid1, cmp_kid2, desc, &new_ops);
03920 break;
03921 default:
03922 FmtAssert(FALSE, ("Unknown opcode"));
03923 }
03924
03925 if (result != true_tn && result != false_tn) {
03926 if (MTYPE_is_float(OPCODE_rtype(select))) {
03927 Build_OP (MTYPE_is_size_double(OPCODE_rtype(select))?TOP_mov_d:TOP_mov_s,
03928 result, true_tn, &new_ops);
03929 } else {
03930 Build_OP (TOP_or, result, Zero_TN, true_tn, &new_ops);
03931 }
03932 }
03933
03934 if (MTYPE_is_float(OPCODE_rtype(select))) {
03935 if (result != false_tn) {
03936 if (MTYPE_is_float(desc))
03937 Build_OP (MTYPE_is_size_double(OPCODE_rtype(select))?TOP_movf_d:TOP_movf_s,
03938 result, false_tn, p, &new_ops);
03939 else Build_OP (MTYPE_is_size_double(OPCODE_rtype(select))?TOP_movz_d:TOP_movz_s,
03940 result, false_tn, p, &new_ops);
03941 } else {
03942 if (MTYPE_is_float(desc))
03943 Build_OP (MTYPE_is_size_double(OPCODE_rtype(select))?TOP_movt_d:TOP_movt_s,
03944 result, true_tn, p, &new_ops);
03945 else Build_OP (MTYPE_is_size_double(OPCODE_rtype(select))?TOP_movn_d:TOP_movn_s,
03946 result, true_tn, p, &new_ops);
03947 }
03948 } else {
03949 if (result != false_tn) {
03950 if (MTYPE_is_float(desc))
03951 Build_OP (TOP_movf, result, false_tn, p, &new_ops);
03952 else Build_OP (TOP_movz, result, false_tn, p, &new_ops);
03953 } else {
03954 if (MTYPE_is_float(desc))
03955 Build_OP (TOP_movt, result, true_tn, p, &new_ops);
03956 else Build_OP (TOP_movn, result, true_tn, p, &new_ops);
03957 }
03958 }
03959 Set_OP_cond_def_kind(OPS_last(&new_ops), OP_ALWAYS_COND_DEF);
03960 if (Trace_Exp) {
03961 OP *op;
03962 FOR_ALL_OPS_OPs (&new_ops, op) {
03963 fprintf(TFile, " into "); Print_OP (op);
03964 }
03965 }
03966 OPS_Append_Ops(ops, &new_ops);
03967 }
03968 #endif
03969
03970 #if defined(TARG_SL)
03971 extern LABEL_IDX
03972 Exp_Select_Part1(
03973 OPCODE select, TN *result, TN *true_tn, TN *false_tn,
03974 OPCODE compare, TN *cmp_kid1, TN *cmp_kid2, OPS *ops)
03975 {
03976 TOP cmp1, cmp2;
03977
03978 if (Trace_Exp) {
03979 fprintf(TFile, "expand %s: ", OPCODE_name(select));
03980 if (result) Print_TN(result,FALSE);
03981 fprintf(TFile, " :- (");
03982 if (cmp_kid1) Print_TN(cmp_kid1,FALSE);
03983 fprintf(TFile, " ");
03984 fprintf(TFile, OPCODE_name(compare));
03985 fprintf(TFile, " ");
03986 if (cmp_kid2) Print_TN(cmp_kid2,FALSE);
03987 fprintf(TFile, ") ? ");
03988 if (true_tn) Print_TN(true_tn,FALSE);
03989 fprintf(TFile, " : ");
03990 if (false_tn) Print_TN(false_tn,FALSE);
03991 fprintf(TFile, "\n");
03992 }
03993
03994 TYPE_ID desc = OPCODE_desc(compare);
03995 Is_True(MTYPE_is_float(desc)==FALSE, ("cannot handle floats"));
03996
03997 OPERATOR compare_opr = OPCODE_operator(compare);
03998 TN *p;
03999 OPS new_ops;
04000 LABEL_IDX merge_lab;
04001
04002 OPS_Init(&new_ops);
04003 p = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
04004
04005 if (compare_opr == OPR_NE) {
04006 TN *tmp = true_tn;
04007 true_tn = false_tn;
04008 false_tn = tmp;
04009 compare_opr = OPR_EQ;
04010 }
04011
04012 switch(compare_opr) {
04013 case OPR_LT:
04014 Expand_Int_Less (p, cmp_kid1, cmp_kid2, desc, &new_ops);
04015 break;
04016 case OPR_LE:
04017 Expand_Int_Less_Equal (p, cmp_kid1, cmp_kid2, desc, &new_ops);
04018 break;
04019 case OPR_EQ:
04020 if (desc == MTYPE_B)
04021 Expand_Bool_Equal (p, cmp_kid1, cmp_kid2, &new_ops);
04022 else
04023 Expand_Int_Equal (p, cmp_kid1, cmp_kid2, desc, &new_ops);
04024 break;
04025 #if 0 // this case avoided by above transformation
04026 case OPR_NE:
04027 if (desc == MTYPE_B)
04028 Expand_Bool_Not_Equal (p, cmp_kid1, cmp_kid2, &new_ops);
04029 else
04030 Expand_Int_Not_Equal (p, cmp_kid1, cmp_kid2, desc, &new_ops);
04031 break;
04032 #endif
04033 case OPR_GE:
04034 Expand_Int_Greater_Equal (p, cmp_kid1, cmp_kid2, desc, &new_ops);
04035 break;
04036 case OPR_GT:
04037 Expand_Int_Greater (p, cmp_kid1, cmp_kid2, desc, &new_ops);
04038 break;
04039 default:
04040 FmtAssert(FALSE, ("Unknown opcode"));
04041 }
04042
04043 if (result != true_tn) {
04044 Build_OP (TOP_or, result, Zero_TN, true_tn, &new_ops);
04045 }
04046
04047 merge_lab = Gen_Temp_Label();
04048 TN *merge_lab_tn = Gen_Label_TN(merge_lab, 0);
04049 Build_OP (TOP_bne, p, Zero_TN, merge_lab_tn, &new_ops);
04050
04051 if (Trace_Exp) {
04052 OP *op;
04053 FOR_ALL_OPS_OPs (&new_ops, op) {
04054 fprintf(TFile, " into "); Print_OP (op);
04055 }
04056 }
04057 OPS_Append_Ops(ops, &new_ops);
04058
04059 return merge_lab;
04060 }
04061 #endif // Expand_Select_Part1
04062
04063
04064
04065 #define RESET_COND_DEF_LAST(ops) Set_OP_cond_def_kind(OPS_last(ops),OP_ALWAYS_UNC_DEF)
04066
04067 static void
04068 Expand_SGI_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
04069 {
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103 }
04104
04105 static void
04106 Expand_Intel_F10_Sqrt(TN *result, TN *src, OPS *ops)
04107 { FmtAssert(FALSE,("Unimplemented")); }
04108
04109
04110 static void
04111 Expand_Intel_Max_Thr_F8_Sqrt(TN *result, TN *src, OPS *ops)
04112 { FmtAssert(FALSE,("Unimplemented")); }
04113
04114
04115 static void
04116 Expand_Intel_Max_Thr_F4_Sqrt(TN *result, TN *src, OPS *ops)
04117 { FmtAssert(FALSE,("Unimplemented")); }
04118
04119
04120 static void
04121 Expand_Intel_Min_Lat_F8_Sqrt(TN *result, TN *src, OPS *ops)
04122 { FmtAssert(FALSE,("Unimplemented")); }
04123
04124
04125 static void
04126 Expand_Intel_Min_Lat_F4_Sqrt(TN *result, TN *src, OPS *ops)
04127 { FmtAssert(FALSE,("Unimplemented")); }
04128
04129
04130 static void
04131 Expand_Intel_Max_Thr_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
04132 {
04133 switch (mtype) {
04134 case MTYPE_F4:
04135 Expand_Intel_Max_Thr_F4_Sqrt(result, src, ops);
04136 break;
04137 case MTYPE_F8:
04138 Expand_Intel_Max_Thr_F8_Sqrt(result, src, ops);
04139 break;
04140 case MTYPE_F10:
04141 Expand_Intel_F10_Sqrt(result, src, ops);
04142 break;
04143 default:
04144 FmtAssert(FALSE, ("Bad type in Expand_Intel_Max_Thr_Sqrt"));
04145
04146 }
04147 }
04148
04149
04150 static void
04151 Expand_Intel_Min_Lat_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
04152 {
04153 switch (mtype) {
04154 case MTYPE_F4:
04155 Expand_Intel_Min_Lat_F4_Sqrt(result, src, ops);
04156 break;
04157 case MTYPE_F8:
04158 Expand_Intel_Min_Lat_F8_Sqrt(result, src, ops);
04159 break;
04160 case MTYPE_F10:
04161 Expand_Intel_F10_Sqrt(result, src, ops);
04162 break;
04163 default:
04164 FmtAssert(FALSE, ("Bad type in Expand_Intel_Min_Lat_Sqrt"));
04165
04166 }
04167 }
04168
04169
04170 void
04171 Expand_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
04172 {
04173 FmtAssert(TN_register_class(result) == ISA_REGISTER_CLASS_float &&
04174 TN_register_class(src) == ISA_REGISTER_CLASS_float,
04175 ("Unimplemented sqrt for integer src/dest"));
04176 Build_OP(MTYPE_is_size_double(mtype)?TOP_sqrt_d:TOP_sqrt_s,
04177 result, src, ops);
04178 }
04179
04180
04181 static void
04182 Expand_Float_Compares(TOP cmp_opcode, TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
04183 {
04184 if (TN_register_class(dest) == ISA_REGISTER_CLASS_fcc) {
04185 FmtAssert(cmp_opcode != TOP_c_neq_d && cmp_opcode != TOP_c_neq_s,
04186 ("Expand_Float_Compares: should not use c_neq_[sd] which is not supported by assembler"));
04187 Build_OP(cmp_opcode, dest, src1, src2, ops);
04188 } else {
04189 FmtAssert(TN_register_class(dest) == ISA_REGISTER_CLASS_integer,
04190 ("Expand_Float_Compares: result must be fcc or integer"));
04191 TN *tmp_fcc = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 1);
04192 Build_OP(MTYPE_is_size_double(mtype)?TOP_daddiu:TOP_addiu,
04193 dest, Zero_TN, Gen_Literal_TN(1, 4), ops);
04194 if (cmp_opcode == TOP_c_neq_d || cmp_opcode == TOP_c_neq_s) {
04195 Build_OP(cmp_opcode == TOP_c_neq_d ? TOP_c_eq_d : TOP_c_eq_s,
04196 tmp_fcc, src1, src2, ops);
04197 Build_OP(TOP_movt, dest, Zero_TN, tmp_fcc, ops);
04198 }
04199 else {
04200 Build_OP(cmp_opcode, tmp_fcc, src1, src2, ops);
04201 Build_OP(TOP_movf, dest, Zero_TN, tmp_fcc, ops);
04202 }
04203 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
04204 }
04205 }
04206
04207 void
04208 Expand_Float_Less (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
04209 {
04210 #if defined(TARG_SL)
04211 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_lt_d:TOP_c_olt_s,
04212 #else
04213 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_lt_d:TOP_c_lt_s,
04214 #endif
04215 dest, src1, src2, mtype, ops);
04216 }
04217
04218 void
04219 Expand_Float_Greater (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
04220 {
04221 #if defined(TARG_SL)
04222 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_lt_d:TOP_c_olt_s,
04223 #else
04224 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_lt_d:TOP_c_lt_s,
04225 #endif
04226 dest, src2, src1, mtype, ops);
04227 }
04228
04229 void
04230 Expand_Float_Less_Equal (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
04231 {
04232 #if defined(TARG_SL)
04233 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_le_d:TOP_c_ole_s,
04234 #else
04235 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_le_d:TOP_c_le_s,
04236 #endif
04237 dest, src1, src2, mtype, ops);
04238 }
04239
04240 void
04241 Expand_Float_Greater_Equal (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
04242 {
04243 #if defined(TARG_SL)
04244 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_le_d:TOP_c_ole_s,
04245 #else
04246 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_le_d:TOP_c_le_s,
04247 #endif
04248 dest, src2, src1, mtype, ops);
04249 }
04250
04251 void
04252 Expand_Float_Equal (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
04253 {
04254 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_eq_d:TOP_c_eq_s,
04255 dest, src1, src2, mtype, ops);
04256 }
04257
04258 void
04259 Expand_Float_Not_Equal (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
04260 {
04261 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_neq_d:TOP_c_neq_s,
04262 dest, src1, src2, mtype, ops);
04263 }
04264
04265 void
04266 Expand_Recip_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
04267 {
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285 }
04286
04287 void
04288 Expand_Flop (OPCODE opcode, TN *result, TN *src1, TN *src2, TN *src3, OPS *ops)
04289 {
04290 TOP opc;
04291
04292 switch (opcode) {
04293 case OPC_F4ADD:
04294 opc = TOP_add_s;
04295 break;
04296 case OPC_F8ADD:
04297 opc = TOP_add_d;
04298 break;
04299 case OPC_F4SUB:
04300 opc = TOP_sub_s;
04301 break;
04302 case OPC_F8SUB:
04303 opc = TOP_sub_d;
04304 break;
04305 case OPC_F4MPY:
04306 opc = TOP_mul_s;
04307 break;
04308 case OPC_F8MPY:
04309 opc = TOP_mul_d;
04310 break;
04311 case OPC_F4MADD:
04312 opc = TOP_madd_s;
04313 break;
04314 case OPC_F4NMADD:
04315 opc = TOP_nmadd_s;
04316 break;
04317 case OPC_F4MSUB:
04318 opc = TOP_msub_s;
04319 break;
04320 case OPC_F4NMSUB:
04321 opc = TOP_nmsub_s;
04322 break;
04323 case OPC_F8MADD:
04324 opc = TOP_madd_d;
04325 break;
04326 case OPC_F8NMADD:
04327 opc = TOP_nmadd_d;
04328 break;
04329 case OPC_F8MSUB:
04330 opc = TOP_msub_d;
04331 break;
04332 case OPC_F8NMSUB:
04333 opc = TOP_nmsub_d;
04334 break;
04335 case OPC_F4DIV:
04336 opc = TOP_div_s;
04337 break;
04338 case OPC_F8DIV:
04339 opc = TOP_div_d;
04340 break;
04341 case OPC_F4RECIP:
04342 opc = TOP_recip_s;
04343 break;
04344 case OPC_F8RECIP:
04345 opc = TOP_recip_d;
04346 break;
04347 case OPC_F4RSQRT:
04348 opc = TOP_rsqrt_s;
04349 break;
04350 case OPC_F8RSQRT:
04351 opc = TOP_rsqrt_d;
04352 break;
04353 default:
04354 #pragma mips_frequency_hint NEVER
04355 FmtAssert(FALSE, ("unexpected opcode %s", OPCODE_name(opcode)));
04356
04357 }
04358 if (TOP_is_madd(opc)) {
04359 Build_OP(opc, result, src1, src2, src3, ops);
04360 } else {
04361 Build_OP(opc, result, src1, src2, ops);
04362 }
04363 }
04364
04365 extern void
04366 Init_CG_Expand (void)
04367 {
04368 static BOOL Initialized = FALSE;
04369
04370
04371 Trace_Exp = Get_Trace (TP_CGEXP, 1);
04372
04373 Trace_Exp2 = Get_Trace (TP_CGEXP, 4);
04374 Disable_Const_Mult_Opt = Get_Trace (TP_CGEXP, 32);
04375
04376 if (Initialized) return;
04377 Initialized = TRUE;
04378
04379 Initialize_Branch_Variants();
04380 }
04381
04382
04383
04384
04385
04386
04387
04388 void
04389 Exp_COPY (TN *tgt_tn, TN *src_tn, OPS *ops)
04390 {
04391 if( TN_is_constant(src_tn) )
04392 {
04393 FmtAssert (TN_has_value(src_tn), ("Exp_COPY: illegal source tn"));
04394
04395 Exp_OP1 (OPC_I4INTCONST, tgt_tn, src_tn, ops);
04396 }
04397 else
04398 {
04399 #if defined(TARG_SL)
04400
04401 Copy_Tn_MapInfo(src_tn, tgt_tn);
04402 #endif
04403
04404 ISA_REGISTER_CLASS tgt_rc = TN_register_class(tgt_tn);
04405 ISA_REGISTER_CLASS src_rc = TN_register_class(src_tn);
04406
04407 if (tgt_rc == src_rc && tgt_rc == ISA_REGISTER_CLASS_integer) {
04408 Build_OP( TOP_or, tgt_tn, src_tn, Zero_TN, ops );
04409 Set_OP_copy (OPS_last(ops));
04410 }
04411 else if (src_tn == tgt_tn)
04412 {
04413
04414
04415
04416 Build_OP(TOP_noop, ops);
04417 }
04418 else if (tgt_rc == src_rc && tgt_rc == ISA_REGISTER_CLASS_float) {
04419
04420 BOOL is_double = (TN_size(tgt_tn) == 8 && TN_size(src_tn) == 8);
04421 Build_OP(is_double ? TOP_mov_d : TOP_mov_s, tgt_tn, src_tn, ops);
04422 Set_OP_copy (OPS_last(ops));
04423 }
04424 #if defined(TARG_SL)
04425 else if (src_rc == ISA_REGISTER_CLASS_control) {
04426 if (src_rc == tgt_rc) {
04427 TN *tmp_tn = Gen_Register_TN (ISA_REGISTER_CLASS_integer, 4);
04428 Build_OP(TOP_mvfc, tmp_tn, src_tn, ops);
04429 Build_OP(TOP_mvtc, tgt_tn, tmp_tn, ops);
04430 } else if (tgt_rc == ISA_REGISTER_CLASS_integer) {
04431 Build_OP(TOP_mvfc, tgt_tn, src_tn, ops);
04432 }
04433 }
04434 else if (tgt_rc == ISA_REGISTER_CLASS_control) {
04435 Is_True(src_rc == ISA_REGISTER_CLASS_integer, ("not supported reg class save"));
04436 Build_OP(TOP_mvtc, tgt_tn, src_tn, ops);
04437 }
04438 else if (src_rc == ISA_REGISTER_CLASS_accum) {
04439 if (src_rc == tgt_rc) {
04440 TN *tmp_tn = Gen_Register_TN (ISA_REGISTER_CLASS_integer, 4);
04441 Build_OP(TOP_c3_mvfacc, tmp_tn, src_tn, ops);
04442 Build_OP(TOP_c3_mvtacc, tgt_tn, tmp_tn, ops);
04443 } else if (tgt_rc == ISA_REGISTER_CLASS_integer) {
04444 Build_OP(TOP_c3_mvfacc, tgt_tn, src_tn, ops);
04445 }
04446 } else if (tgt_rc == ISA_REGISTER_CLASS_accum) {
04447 Is_True(src_rc == ISA_REGISTER_CLASS_integer, ("not supported reg class save"));
04448 Build_OP(TOP_c3_mvtacc, tgt_tn, src_tn, ops);
04449 }
04450 else if (src_rc == ISA_REGISTER_CLASS_addr) {
04451 if (src_rc == tgt_rc) {
04452 TN *tmp_tn = Gen_Register_TN (ISA_REGISTER_CLASS_integer, 4);
04453 Build_OP(TOP_c3_mvfaddr, tmp_tn, src_tn, ops);
04454 Build_OP(TOP_c3_mvtaddr, tgt_tn, tmp_tn, ops);
04455 } else if (tgt_rc == ISA_REGISTER_CLASS_integer) {
04456 Build_OP(TOP_c3_mvfaddr, tgt_tn, src_tn, ops);
04457 }
04458 } else if (tgt_rc == ISA_REGISTER_CLASS_addr) {
04459 Is_True(src_rc == ISA_REGISTER_CLASS_integer, ("not supported reg class save"));
04460 Build_OP(TOP_c3_mvtaddr, tgt_tn, src_tn, ops);
04461 }
04462 #endif
04463
04464 else
04465 {
04466
04467 BOOL is_double = (TN_size(tgt_tn) == 8 && TN_size(src_tn) == 8);
04468 if (src_rc == ISA_REGISTER_CLASS_integer) {
04469 Build_OP(is_double ? TOP_dmtc1 : TOP_mtc1, tgt_tn, src_tn, ops);
04470 } else if (src_rc == ISA_REGISTER_CLASS_float) {
04471 Build_OP(is_double ? TOP_dmfc1 : TOP_mfc1, tgt_tn, src_tn, ops);
04472 } else {
04473 FmtAssert(FALSE, ("Unimplemented Copy.\n"));
04474 }
04475 }
04476 }
04477 }
04478
04479 static ST *tmp_apply_arg = NULL;
04480 void
04481 Generate_Temp_Apply_Arg ( )
04482 {
04483 TY_IDX tyi;
04484 TY& ty = New_TY(tyi);
04485 TY_Init(ty, 144, KIND_STRUCT, MTYPE_M,
04486 Save_Str("__apply_arg"));
04487 Set_TY_align(tyi, 8);
04488 tmp_apply_arg = New_ST(CURRENT_SYMTAB);
04489 ST_Init(tmp_apply_arg, TY_name_idx(ty),
04490 CLASS_VAR, SCLASS_AUTO, EXPORT_LOCAL, tyi);
04491 Set_ST_is_temp_var(tmp_apply_arg);
04492 Allocate_Object(tmp_apply_arg);
04493 }
04494
04495 void
04496 Exp_Intrinsic_Op (INTRINSIC id, TN *result, TN *op0, TN *op1, TYPE_ID mtype, OPS *ops)
04497 {
04498 FmtAssert(FALSE, ("Exp_Intrinsic_Op NYI"));
04499 return;
04500 }
04501
04502
04503
04504
04505
04506
04507
04508
04509
04510 static INT
04511 Expand_TOP_intrncall (
04512 const OP *op,
04513 OPS *ops,
04514 BOOL get_sequence_length,
04515 INT pc_value)
04516 {
04517 FmtAssert(FALSE, ("Expand_TOP_intrncall NYI"));
04518 return 0;
04519 }
04520
04521 static TYPE_ID
04522 Get_Intrinsic_Size_Mtype (INTRINSIC id)
04523 {
04524 switch (id) {
04525 case INTRN_COMPARE_AND_SWAP_I4:
04526 case INTRN_LOCK_TEST_AND_SET_I4:
04527 case INTRN_LOCK_RELEASE_I4:
04528 case INTRN_FETCH_AND_ADD_I4:
04529 case INTRN_ADD_AND_FETCH_I4:
04530 case INTRN_SUB_AND_FETCH_I4:
04531 case INTRN_OR_AND_FETCH_I4:
04532 case INTRN_XOR_AND_FETCH_I4:
04533 case INTRN_AND_AND_FETCH_I4:
04534 case INTRN_NAND_AND_FETCH_I4:
04535 case INTRN_FETCH_AND_SUB_I4:
04536 case INTRN_FETCH_AND_OR_I4:
04537 case INTRN_FETCH_AND_XOR_I4:
04538 case INTRN_FETCH_AND_AND_I4:
04539 case INTRN_FETCH_AND_NAND_I4:
04540 return MTYPE_I4;
04541 case INTRN_COMPARE_AND_SWAP_I8:
04542 case INTRN_LOCK_TEST_AND_SET_I8:
04543 case INTRN_LOCK_RELEASE_I8:
04544 case INTRN_FETCH_AND_ADD_I8:
04545 case INTRN_ADD_AND_FETCH_I8:
04546 case INTRN_SUB_AND_FETCH_I8:
04547 case INTRN_OR_AND_FETCH_I8:
04548 case INTRN_XOR_AND_FETCH_I8:
04549 case INTRN_AND_AND_FETCH_I8:
04550 case INTRN_NAND_AND_FETCH_I8:
04551 case INTRN_FETCH_AND_SUB_I8:
04552 case INTRN_FETCH_AND_OR_I8:
04553 case INTRN_FETCH_AND_XOR_I8:
04554 case INTRN_FETCH_AND_AND_I8:
04555 case INTRN_FETCH_AND_NAND_I8:
04556 case INTRN_SYNCHRONIZE:
04557 return MTYPE_I8;
04558 default:
04559 FmtAssert(FALSE, ("Unexpected intrinsic %d", id));
04560 return MTYPE_UNKNOWN;
04561 }
04562 }
04563
04564 static BOOL
04565 Intrinsic_Returns_New_Value (INTRINSIC id)
04566 {
04567 switch (id) {
04568 case INTRN_ADD_AND_FETCH_I4:
04569 case INTRN_SUB_AND_FETCH_I4:
04570 case INTRN_OR_AND_FETCH_I4:
04571 case INTRN_XOR_AND_FETCH_I4:
04572 case INTRN_AND_AND_FETCH_I4:
04573 case INTRN_NAND_AND_FETCH_I4:
04574 case INTRN_ADD_AND_FETCH_I8:
04575 case INTRN_SUB_AND_FETCH_I8:
04576 case INTRN_OR_AND_FETCH_I8:
04577 case INTRN_XOR_AND_FETCH_I8:
04578 case INTRN_AND_AND_FETCH_I8:
04579 case INTRN_NAND_AND_FETCH_I8:
04580 return TRUE;
04581 default:
04582 return FALSE;
04583 }
04584 }
04585
04586 #if defined(TARG_SL)
04587
04588
04589 #define INVALID_CONST -1
04590
04591 TOP
04592 Analyze_SL2_Intrinsic( INTRINSIC id, WN* intrncall ) {
04593
04594 UINT32 op_type, sign;
04595
04596 INT32 opnds[15];
04597
04598 UINT32 opnds_num = WN_kid_count(intrncall);
04599
04600
04601
04602 for(int i = 0; i < opnds_num; i++) {
04603 WN* ith_parm = WN_kid(intrncall, i);
04604 WN* kid0 = WN_kid0(ith_parm);
04605 if(WN_operator(kid0)==OPR_INTCONST)
04606 opnds[i] = WN_const_val(WN_kid0(WN_kid(intrncall, i)));
04607 else
04608 opnds[i] = INVALID_CONST;
04609 }
04610
04611 switch (id) {
04612 case INTRN_C2_MVGR_R2G:
04613 if(opnds[2]==0 && opnds[4]<2 && opnds[3]==0)
04614 return TOP_c2_mvgr_r2g_h_u_i;
04615 else if(opnds[2]==0 && opnds[4]<2 && opnds[3]==1)
04616 return TOP_c2_mvgr_r2g_h_i;
04617 else if(opnds[2]==0 && opnds[4]>=2)
04618 return TOP_c2_mvgr_r2g_w_i;
04619 else if(opnds[2]==1 && opnds[4]<2 && opnds[3]==0)
04620 return TOP_c2_mvgr_r2g_h_u;
04621 else if(opnds[2]==1 && opnds[4]<2 && opnds[3]==1)
04622 return TOP_c2_mvgr_r2g_h;
04623 else if(opnds[2]==1 && opnds[4]>=2)
04624 return TOP_c2_mvgr_r2g_w;
04625 else {
04626 FmtAssert(FALSE, ("invalid parameter in function c2_mvgr_r2g"));
04627 }
04628 break;
04629 case INTRN_C2_MVGR_G2R:
04630
04631 if(opnds[3]==0 && opnds[6]==0)
04632 return TOP_c2_mvgr_g2r_ba_lh;
04633 else if(opnds[3]==0 && opnds[6]==1)
04634 return TOP_c2_mvgr_g2r_ba_hh;
04635 else if(opnds[3]==0 && opnds[6]==2)
04636 return TOP_c2_mvgr_g2r_ba_w;
04637 else if(opnds[3]==1 && opnds[6]==0 && opnds[7] == 1)
04638 return TOP_c2_mvgr_g2r_lh_i;
04639 else if(opnds[3]==1 && opnds[6]==1 && opnds[7] == 1)
04640 return TOP_c2_mvgr_g2r_hh_i;
04641 else if(opnds[3]==1 && opnds[6]==2 && opnds[7] == 1)
04642 return TOP_c2_mvgr_g2r_w_i;
04643 else if(opnds[3]==1 && opnds[6]==0 && opnds[7] == 0)
04644 return TOP_c2_mvgr_g2r_lh;
04645 else if(opnds[3]==1 && opnds[6]==1 && opnds[7] == 0)
04646 return TOP_c2_mvgr_g2r_hh;
04647 else if(opnds[3]==1 && opnds[6]==2 && opnds[7] == 0)
04648 return TOP_c2_mvgr_g2r_w;
04649 else if(opnds[3]==2 && opnds[4]==0 && opnds[5]==1)
04650 return TOP_c2_mvgr_g2r_bh;
04651 else if(opnds[3]==2 && opnds[4]==0 && opnds[5]==0)
04652 return TOP_c2_mvgr_g2r_bh_u;
04653 else if(opnds[3]==2 && opnds[4]==1 && opnds[5]==1)
04654 return TOP_c2_mvgr_g2r_bv;
04655 else if(opnds[3]==2 && opnds[4]==1 && opnds[5]==0)
04656 return TOP_c2_mvgr_g2r_bv_u;
04657 else if(opnds[3]==3 && opnds[7] == 1)
04658 return TOP_c2_mvgr_g2r_b4_i;
04659 else if(opnds[3]==3 && opnds[7] == 0)
04660 return TOP_c2_mvgr_g2r_b4;
04661 else {
04662 FmtAssert(FALSE, ("invalid parameter in function c2_mvgr_g2r"));
04663 }
04664 break;
04665 case INTRN_C2_MVGC_C2G:
04666 return TOP_c2_mvgc_c2g;
04667 break;
04668 case INTRN_C2_MVGC_G2C:
04669 return TOP_c2_mvgc_g2c;
04670 break;
04671 case INTRN_C2_LD_V:
04672 if(opnds[3]==0 && opnds[2]==0 && opnds[5]>=2 && opnds[4]==0)
04673 return TOP_c2_ld_v_b_u;
04674 else if(opnds[3]==0 && opnds[2]==0 && opnds[5]>=2 && opnds[4]==1)
04675 return TOP_c2_ld_v_b;
04676 else if(opnds[3]==0 && opnds[2]==0 && opnds[5]==0)
04677 return TOP_c2_ld_v_h;
04678 else if(opnds[3]==0 && opnds[2]==0 && opnds[5]==1)
04679 return TOP_c2_ld_v_w;
04680 else if(opnds[3]==0 && opnds[2]==1)
04681 return TOP_c2_ld_v_sw;
04682 else if(opnds[3]==1 && opnds[5]>=2 && opnds[4]==0)
04683 return TOP_c2_ld_v_m_b_u;
04684 else if(opnds[3]==1 && opnds[5]>=2 && opnds[4]==1)
04685 return TOP_c2_ld_v_m_b;
04686 else if(opnds[3]==1 && opnds[5]==0)
04687 return TOP_c2_ld_v_m_h;
04688 else if(opnds[3]==1 && opnds[5]==1)
04689 return TOP_c2_ld_v_m_w;
04690 else {
04691 FmtAssert(FALSE, ("invalid parameter in function c2_ld_v"));
04692 }
04693 break;
04694 case INTRN_C2_LD_G:
04695 if(opnds[3]==0 && opnds[2]==0 && opnds[1]==1)
04696 return TOP_c2_ld_s_h_u_p;
04697 else if(opnds[3]==0 && opnds[2]==0 && opnds[1]==0)
04698 return TOP_c2_ld_s_h_u;
04699 else if(opnds[3]==0 && opnds[2]==1 && opnds[1]==1)
04700 return TOP_c2_ld_s_h_p;
04701 else if(opnds[3]==0 && opnds[2]==1 && opnds[1]==0)
04702 return TOP_c2_ld_s_h;
04703 else if(opnds[3]==1 && opnds[1]==1)
04704 return TOP_c2_ld_s_w_p;
04705 else if(opnds[3]==1 && opnds[1]==0)
04706 return TOP_c2_ld_s_w;
04707 else {
04708 FmtAssert(FALSE, ("invalid parameter in function c2_ld_g"));
04709 }
04710 break;
04711 case INTRN_C2_ST_V:
04712 if(opnds[2]==0 && opnds[3]>=2)
04713 return TOP_c2_st_v_b;
04714 else if(opnds[2]==0 && opnds[3]==0)
04715 return TOP_c2_st_v_h;
04716 else if(opnds[2]==0 && opnds[3]==1)
04717 return TOP_c2_st_v_w;
04718 else if(opnds[2]==1 && opnds[3]>=2)
04719 return TOP_c2_st_v_m_b;
04720 else if(opnds[2]==1 && opnds[3]==0)
04721 return TOP_c2_st_v_m_h;
04722 else if(opnds[2]==1 && opnds[3]==1)
04723 return TOP_c2_st_v_m_w;
04724 else {
04725 FmtAssert(FALSE, ("invalid parameter in function c2_st_v"));
04726 }
04727 break;
04728 case INTRN_C2_ST_G:
04729 if(opnds[3]==0 && opnds[2]==0)
04730 return TOP_c2_st_s_h;
04731 else if(opnds[3]==0 && opnds[2]==1)
04732 return TOP_c2_st_s_h_p;
04733 else if(opnds[3]==1 && opnds[2]==0)
04734 return TOP_c2_st_s_w;
04735 else if(opnds[3]==1 && opnds[2]==1)
04736 return TOP_c2_st_s_w_p;
04737 else {
04738 FmtAssert(FALSE, ("invalid parameter in function c2_st_g"));
04739 }
04740 break;
04741 case INTRN_C2_LD_G_IMM:
04742 if(opnds[1]==0 && opnds[0]==0)
04743 return TOP_c2_ldi_s_h_u;
04744 else if(opnds[1]==0 && opnds[0]==1)
04745 return TOP_c2_ldi_s_h;
04746 else if(opnds[1]==1)
04747 return TOP_c2_ldi_s_w;
04748 else {
04749 FmtAssert(FALSE, ("invalid parameter in function c2_ld_g_imm"));
04750 }
04751 break;
04752 case INTRN_C2_LD_C_IMM:
04753 return TOP_c2_ldi_c;
04754 break;
04755 case INTRN_C2_LD_V_IMM:
04756 if(opnds[1]==0 && opnds[3]>=2 && opnds[2]==0)
04757 return TOP_c2_ldi_v_b_u;
04758 else if(opnds[1]==0 && opnds[3]>=2 && opnds[2]==1)
04759 return TOP_c2_ldi_v_b;
04760 else if(opnds[1]==0 && opnds[3]==0)
04761 return TOP_c2_ldi_v_h;
04762 else if(opnds[1]==0 && opnds[3]==1)
04763 return TOP_c2_ldi_v_w;
04764 else if(opnds[1]==1 && opnds[3]>=2 && opnds[2]==0)
04765 return TOP_c2_ldi_v_m_b_u;
04766 else if(opnds[1]==1 && opnds[3]>=2 && opnds[2]==1)
04767 return TOP_c2_ldi_v_m_b;
04768 else if(opnds[1]==1 && opnds[3]==0)
04769 return TOP_c2_ldi_v_m_h;
04770 else if(opnds[1]==1 && opnds[3]==1)
04771 return TOP_c2_ldi_v_m_w;
04772 else {
04773 FmtAssert(FALSE, ("invalid parameter in function c2_ld_v_imm"));
04774 }
04775 break;
04776 case INTRN_C2_ST_V_IMM:
04777 if(opnds[2]==0 && opnds[1]>=2)
04778 return TOP_c2_sti_v_b;
04779 else if(opnds[2]==0 && opnds[1]==0)
04780 return TOP_c2_sti_v_h;
04781 else if(opnds[2]==0 && opnds[1]==1)
04782 return TOP_c2_sti_v_w;
04783 else if(opnds[2]==1 && opnds[1]>=2)
04784 return TOP_c2_sti_v_m_b;
04785 else if(opnds[2]==1 && opnds[1]==0)
04786 return TOP_c2_sti_v_m_h;
04787 else if(opnds[2]==1 && opnds[1]==1)
04788 return TOP_c2_sti_v_m_w;
04789 else {
04790 FmtAssert(FALSE, ("invalid parameter in function c2_st_v_imm"));
04791 }
04792 break;
04793 case INTRN_C2_ST_C_IMM:
04794 return TOP_c2_sti_c;
04795 break;
04796 case INTRN_C2_ST_G_IMM:
04797 if(opnds[1]==0)
04798 return TOP_c2_sti_s_h;
04799 else if(opnds[1]==1)
04800 return TOP_c2_sti_s_w;
04801 else {
04802 FmtAssert(FALSE, ("invalid parameter in function c2_st_g_imm"));
04803 }
04804 break;
04805 case INTRN_C2_VADDS:
04806 if( opnds[4]==0 && opnds[3]==0 && (opnds[6]&6)==6)
04807 return TOP_c2_vadds_h_mode6;
04808 else if (opnds[4]==0 && opnds[3]==0 && (opnds[6]&6)==2)
04809 return TOP_c2_vadds_h_mode2;
04810 else if( opnds[4]==0 && opnds[3]==0)
04811 return TOP_c2_vadds_h;
04812 else if( opnds[4]==0 && opnds[3]==1 && (opnds[6]&6)==6)
04813 return TOP_c2_vadds_w_mode6;
04814 else if(opnds[4]==0 && opnds[3]==1 && (opnds[6]&6)==2)
04815 return TOP_c2_vadds_w_mode2;
04816 else if( opnds[4]==0 && opnds[3]==1)
04817 return TOP_c2_vadds_w;
04818 else if( opnds[4]==1 && (opnds[6]&6)==6)
04819 return TOP_c2_vadds_p_mode6;
04820 else if( opnds[4]==1 && (opnds[6]&6)==2)
04821 return TOP_c2_vadds_p_mode2;
04822 else if( opnds[4]==1)
04823 return TOP_c2_vadds_p;
04824 else {
04825 FmtAssert(FALSE, ("invalid parameter in function c2_vadds"));
04826 }
04827 break;
04828 case INTRN_C2_VSUBS:
04829 if(opnds[4]==0 && opnds[3]==0 && opnds[5]==0 && (opnds[7]&0x2)==2)
04830 return TOP_c2_vsubs_h_sm;
04831 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==0 )
04832 return TOP_c2_vsubs_h;
04833 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==1 && (opnds[7]&0x2)==2)
04834 return TOP_c2_vsubs_h_abs_sm;
04835 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==1)
04836 return TOP_c2_vsubs_h_abs;
04837 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==2 && (opnds[7]&0x2)==2)
04838 return TOP_c2_vabs_h_sm;
04839 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==2)
04840 return TOP_c2_vabs_h;
04841 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==0 && (opnds[7]&0x2)==2)
04842 return TOP_c2_vsubs_w_sm;
04843 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==0)
04844 return TOP_c2_vsubs_w;
04845 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==1 && (opnds[7]&0x2)==2)
04846 return TOP_c2_vsubs_w_abs_sm;
04847 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==1)
04848 return TOP_c2_vsubs_w_abs;
04849 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==2 && (opnds[7]&0x2)==2)
04850 return TOP_c2_vabs_w_sm;
04851 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==2)
04852 return TOP_c2_vabs_w;
04853 else if(opnds[4]==1 && opnds[5]==0 && (opnds[7]&0x2)==2)
04854 return TOP_c2_vsubs_p_sm;
04855 else if(opnds[4]==1 && opnds[5]==0)
04856 return TOP_c2_vsubs_p;
04857 else if(opnds[4]==1 && opnds[5]==1 && (opnds[7]&0x2)==2)
04858 return TOP_c2_vsubs_p_abs_sm;
04859 else if(opnds[4]==1 && opnds[5]==1)
04860 return TOP_c2_vsubs_p_abs;
04861 else if(opnds[4]==1 && opnds[5]==2 && (opnds[7]&0x2)==2)
04862 return TOP_c2_vabs_p_sm;
04863 else if(opnds[4]==1 && opnds[5]==2)
04864 return TOP_c2_vabs_p;
04865 else {
04866 FmtAssert(FALSE, ("invalid parameter in function c2_vsubs"));
04867 }
04868 break;
04869 case INTRN_C2_VMUL:
04870 if(opnds[3]==0)
04871 return TOP_c2_vmul_h;
04872 else if(opnds[3]==1)
04873 return TOP_c2_vmul_w;
04874 else {
04875 FmtAssert(FALSE, ("invalid parameter in function c2_vmul"));
04876 }
04877 break;
04878 case INTRN_C2_VNEG:
04879 if(opnds[4]==0 && opnds[3]==0)
04880 return TOP_c2_vneg_h;
04881 else if(opnds[4]==0 && opnds[3]==1)
04882 return TOP_c2_vneg_w;
04883 else if(opnds[4]==1)
04884 return TOP_c2_vneg_p;
04885 else {
04886 FmtAssert(FALSE, ("invalid parameter in function c2_vneg"));
04887 }
04888 break;
04889 case INTRN_C2_VSHFT:
04890 if(opnds[4]==0 && opnds[3]==1)
04891 return TOP_c2_vshr_p;
04892 else if(opnds[4]==0 && opnds[3]==0 && opnds[2]==0)
04893 return TOP_c2_vshr_h;
04894 else if(opnds[4]==0 && opnds[3]==0 && opnds[2]==1)
04895 return TOP_c2_vshr_w;
04896 else if(opnds[4]==1 && opnds[3]==1)
04897 return TOP_c2_vshl_p;
04898 else if(opnds[4]==1 && opnds[3]==0 && opnds[2]==0)
04899 return TOP_c2_vshl_h;
04900 else if(opnds[4]==1 && opnds[3]==0 && opnds[2]==1)
04901 return TOP_c2_vshl_w;
04902 else {
04903 FmtAssert(FALSE, ("invalid parameter in function c2_vshft"));
04904 }
04905 break;
04906 case INTRN_C2_VCLP:
04907 if(opnds[4]==0 && opnds[3]==0)
04908 return TOP_c2_vclp;
04909 else if(opnds[4]==0 && opnds[3]==1)
04910 return TOP_c2_vclp_p;
04911 else if(opnds[4]==1)
04912 return TOP_c2_vclp_a;
04913 else if(opnds[4]==2)
04914 return TOP_c2_vclp_s;
04915 else if(opnds[4]==3)
04916 return TOP_c2_vclp_2;
04917 else if(opnds[4]==4)
04918 return TOP_c2_vclp_n;
04919 else {
04920 FmtAssert(FALSE, ("invalid parameter in function c2_vclp"));
04921 }
04922 break;
04923 case INTRN_C2_VCLG:
04924 if(opnds[4]==0 && opnds[3]==0 && opnds[5]==0)
04925 return TOP_c2_vclg_h_lt_and;
04926 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==1)
04927 return TOP_c2_vclg_h_lt_or;
04928 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==2)
04929 return TOP_c2_vclg_h_le_and;
04930 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==3)
04931 return TOP_c2_vclg_h_le_or;
04932 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==4)
04933 return TOP_c2_vclg_h_eq_and;
04934 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==5)
04935 return TOP_c2_vclg_h_eq_or;
04936 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==6)
04937 return TOP_c2_vclg_h_ge_and;
04938 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==7)
04939 return TOP_c2_vclg_h_ge_or;
04940 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==8)
04941 return TOP_c2_vclg_h_gt_and;
04942 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==9)
04943 return TOP_c2_vclg_h_gt_or;
04944 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==10)
04945 return TOP_c2_vclg_h_and;
04946 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==11)
04947 return TOP_c2_vclg_h_or;
04948 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==12)
04949 return TOP_c2_vclg_h_le;
04950 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==13)
04951 return TOP_c2_vclg_h_lt;
04952 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==14)
04953 return TOP_c2_vclg_h_ge;
04954 else if(opnds[4]==0 && opnds[3]==0 && opnds[5]==15)
04955 return TOP_c2_vclg_h_gt;
04956 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==0)
04957 return TOP_c2_vclg_w_lt_and;
04958 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==1)
04959 return TOP_c2_vclg_w_lt_or;
04960 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==2)
04961 return TOP_c2_vclg_w_le_and;
04962 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==3)
04963 return TOP_c2_vclg_w_le_or;
04964 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==4)
04965 return TOP_c2_vclg_w_eq_and;
04966 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==5)
04967 return TOP_c2_vclg_w_eq_or;
04968 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==6)
04969 return TOP_c2_vclg_w_ge_and;
04970 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==7)
04971 return TOP_c2_vclg_w_ge_or;
04972 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==8)
04973 return TOP_c2_vclg_w_gt_and;
04974 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==9)
04975 return TOP_c2_vclg_w_gt_or;
04976 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==10)
04977 return TOP_c2_vclg_w_and;
04978 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==11)
04979 return TOP_c2_vclg_w_or;
04980 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==12)
04981 return TOP_c2_vclg_w_le;
04982 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==13)
04983 return TOP_c2_vclg_w_lt;
04984 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==14)
04985 return TOP_c2_vclg_w_ge;
04986 else if(opnds[4]==0 && opnds[3]==1 && opnds[5]==15)
04987 return TOP_c2_vclg_w_gt;
04988 else if(opnds[4]==1 && opnds[5]==12)
04989 return TOP_c2_vclg_p_le;
04990 else if(opnds[4]==1 && opnds[5]==13)
04991 return TOP_c2_vclg_p_eq;
04992 else if(opnds[4]==1 && opnds[5]==14)
04993 return TOP_c2_vclg_p_ge;
04994 else if(opnds[4]==1 && opnds[5]==15)
04995 return TOP_c2_vclg_p_gt;
04996 else {
04997 FmtAssert(FALSE, ("invalid parameter in function c2_vclg"));
04998 }
04999 break;
05000 case INTRN_C2_VCMOV:
05001 if(opnds[3]==0 && opnds[4]==0)
05002 return TOP_c2_vcmov_h_f;
05003 else if(opnds[3]==0 && opnds[4]==1)
05004 return TOP_c2_vcmov_h_t;
05005 else if(opnds[3]==1 && opnds[4]==0)
05006 return TOP_c2_vcmov_w_f;
05007 else if(opnds[3]==1 && opnds[4]==1)
05008 return TOP_c2_vcmov_w_t;
05009 else {
05010 FmtAssert(FALSE, ("invalid parameter in function c2_vcmov"));
05011 }
05012 break;
05013 case INTRN_C2_LCZERO:
05014 if(opnds[3] == 1 )
05015 return TOP_c2_lczero_z;
05016 else if (opnds[3] == 0 && opnds[2] == 1)
05017 return TOP_c2_lczero_nz_fw;
05018 else if (opnds[3] == 0 && opnds[2] == 0)
05019 return TOP_c2_lczero_nz_bw;
05020 else {
05021 FmtAssert(FALSE, ("invalid parameter in function c2_lczero"));
05022 }
05023 break;
05024 case INTRN_C2_VRND:
05025 if(opnds[2]==0)
05026 return TOP_c2_vrnd_h;
05027 else if(opnds[2]==1)
05028 return TOP_c2_vrnd_w;
05029 else {
05030 FmtAssert(FALSE, ("invalid parameter in function c2_vrnd"));
05031 }
05032 break;
05033 case INTRN_C2_VSPAS:
05034 return TOP_c2_vspas;
05035 break;
05036 case INTRN_C2_VSPEL:
05037 if(opnds[2]==0 && opnds[3] == 0)
05038 return TOP_c2_vspel_mul_h;
05039 else if(opnds[2] == 0 && opnds[3] == 1)
05040 return TOP_c2_vspel_mul_w;
05041 else if(opnds[2]==1 )
05042 return TOP_c2_vspel_adds;
05043 else {
05044 FmtAssert(FALSE, ("invalid parameter in function c2_vspel"));
05045 }
05046 break;
05047
05048 case INTRN_C2_VSPEL_MAC:
05049 if(opnds[3] == 0)
05050 return TOP_c2_vspel_mac_h;
05051 else if(opnds[3] == 1)
05052 return TOP_c2_vspel_mac_w;
05053 else {
05054 FmtAssert(FALSE, ("invalid parameter in function c2_vspel"));
05055 }
05056 break;
05057 case INTRN_C2_MMUL:
05058 if(opnds[3]==0)
05059 return TOP_c2_mmul_h;
05060 else if(opnds[3]==1)
05061 return TOP_c2_mmul_w;
05062 else {
05063 FmtAssert(FALSE, ("invalid parameter in function c2_mmul_s4"));
05064 }
05065 break;
05066 case INTRN_C2_VMOV:
05067 if(opnds[3]==0)
05068 return TOP_c2_vmov;
05069 else if(opnds[3]==1)
05070 return TOP_c2_vmov_swin;
05071 else {
05072 FmtAssert(FALSE, ("invalid parameter in function c2_vmov"));
05073 }
05074 break;
05075 case INTRN_C2_VCOPY:
05076 return TOP_c2_vcopy;
05077 case INTRN_C2_VCMPR:
05078 if(opnds[3]==0 && opnds[4]==1)
05079 return TOP_c2_vcmpr_h_eq;
05080 else if(opnds[3]==0 && opnds[4]==2)
05081 return TOP_c2_vcmpr_h_lt;
05082 else if(opnds[3]==0 && opnds[4]==3)
05083 return TOP_c2_vcmpr_h_le;
05084 else if(opnds[3]==0 && opnds[4]==4)
05085 return TOP_c2_vcmpr_h_gt;
05086 else if(opnds[3]==0 && opnds[4]==5)
05087 return TOP_c2_vcmpr_h_ge;
05088 else if(opnds[3]==1 && opnds[4]==1)
05089 return TOP_c2_vcmpr_w_eq;
05090 else if(opnds[3]==1 && opnds[4]==2)
05091 return TOP_c2_vcmpr_w_lt;
05092 else if(opnds[3]==1 && opnds[4]==3)
05093 return TOP_c2_vcmpr_w_le;
05094 else if(opnds[3]==1 && opnds[4]==4)
05095 return TOP_c2_vcmpr_w_gt;
05096 else if(opnds[3]==1 && opnds[4]==5)
05097 return TOP_c2_vcmpr_w_ge;
05098 else {
05099 FmtAssert(FALSE, ("invalid parameter in function c2_vcmpr"));
05100 }
05101 break;
05102 case INTRN_C2_SAD:
05103 return TOP_c2_sad;
05104 break;
05105 case INTRN_C2_SATD:
05106 return TOP_c2_satd;
05107 break;
05108 case INTRN_C2_INTRA:
05109 switch(opnds[2])
05110 {
05111 case 0:
05112 case 1:
05113 case 9:
05114 case 14:
05115 case 16:
05116 return TOP_c2_intra_0_1_9_14_16;
05117 break;
05118 case 2:
05119 case 3:
05120 case 8:
05121 case 10:
05122 return TOP_c2_intra_2_3_8_10;
05123 break;
05124 case 4:
05125 return TOP_c2_intra_4;
05126 break;
05127 case 5:
05128 case 11:
05129 return TOP_c2_intra_5_11;
05130 break;
05131 case 6:
05132 return TOP_c2_intra_6;
05133 break;
05134 case 7:
05135 return TOP_c2_intra_7;
05136 break;
05137 case 12:
05138 case 13:
05139 return TOP_c2_intra_12_13;
05140 break;
05141 case 15:
05142 case 17:
05143 return TOP_c2_intra_15_17;
05144 default:
05145 FmtAssert(FALSE, ("invalid op_mode in function c2_intra"));
05146 }
05147 break;
05148 case INTRN_C2_MVSEL:
05149 {
05150 switch (opnds[2]) {
05151 case 0:
05152 return TOP_c2_mvsel_mode0;
05153 case 1:
05154 return TOP_c2_mvsel_mode1;
05155 case 2:
05156 return TOP_c2_mvsel_mode2;
05157 case 3:
05158 case 4:
05159 case 5:
05160 return TOP_c2_mvsel_mode345;
05161 default:
05162 FmtAssert(FALSE, ("invalid op_mode in function c2_mvsel"));
05163 }
05164 }
05165 break;
05166 case INTRN_C2_BCST:
05167 if(opnds[1]==0)
05168 return TOP_c2_bcst_q;
05169 else if(opnds[1]==1)
05170 return TOP_c2_bcst_i;
05171 else {
05172 FmtAssert(FALSE, ("invalid parameter in function c2_bcst"));
05173 }
05174 break;
05175 case INTRN_C2_VLCS:
05176 return TOP_c2_vlcs_wb;
05177 case INTRN_C2_VLCS_R:
05178 if(opnds[2]==0)
05179 return TOP_c2_vlcs_dc;
05180 else if(opnds[2]==2)
05181 return TOP_c2_vlcs_ac;
05182 else
05183 FmtAssert(FALSE, ("invalid parameter in function c2_vlcs"));
05184 break;
05185 case INTRN_C2_ADDS:
05186 if(opnds[2]==1 && opnds[6] == 1)
05187 return TOP_c2_add_shl_g_i;
05188 else if(opnds[2]==1 && opnds[6] == 0)
05189 return TOP_c2_add_shr_g_i;
05190 else if(opnds[2] == 0 && opnds[6]== 1)
05191 return TOP_c2_add_shl_g;
05192 else if(opnds[2] == 0 && opnds[6] == 0)
05193 return TOP_c2_add_shr_g;
05194 else
05195 FmtAssert(FALSE, ("invalid parameter in function c2_adds"));
05196 break;
05197 case INTRN_C2_ADDS_R:
05198
05199 if(opnds[4]==1 && opnds[3]==0 && opnds[8] == 1)
05200 return TOP_c2_add_shl_r_h_i;
05201 else if(opnds[4]==1 && opnds[3]==0 && opnds[8] == 0 )
05202 return TOP_c2_add_shr_r_h_i;
05203 else if(opnds[4]==1 && opnds[3]==1 && opnds[8] == 1 )
05204 return TOP_c2_add_shl_r_w_i;
05205 else if(opnds[4]==1 && opnds[3]==1 && opnds[8] == 0 )
05206 return TOP_c2_add_shr_r_w_i;
05207 else if(opnds[4]==0 && opnds[3]==0 && opnds[8] == 1 )
05208 return TOP_c2_add_shl_r_h;
05209 else if(opnds[4]==0 && opnds[3]==0 && opnds[8] == 0 )
05210 return TOP_c2_add_shr_r_h;
05211 else if(opnds[4]==0 && opnds[3]==1 && opnds[8] == 1 )
05212 return TOP_c2_add_shl_r_w;
05213 else if(opnds[4]==0 && opnds[3]==1 && opnds[8] == 0 )
05214 return TOP_c2_add_shr_r_w;
05215 else
05216 FmtAssert(FALSE, ("invalid parameter in function c2_adds_r"));
05217 break;
05218 case INTRN_C2_SUBS:
05219 if(opnds[2]==1 && opnds[3]==1)
05220 return TOP_c2_sub_g_abs_i;
05221 else if(opnds[2]==1 && opnds[3]==0)
05222 return TOP_c2_subs_g_i;
05223 else if(opnds[2]==0 && opnds[3]==1)
05224 return TOP_c2_sub_g_abs;
05225 else if(opnds[2]==0 && opnds[3]==0)
05226 return TOP_c2_subs_g;
05227 else {
05228 FmtAssert(FALSE, ("invalid parameter in function c2_sub"));
05229 }
05230 break;
05231 case INTRN_C2_SUBS_R:
05232 if( opnds[4]==1 && opnds[5]==0 && opnds[3]==0)
05233 return TOP_c2_subs_r_h_i;
05234 else if( opnds[4]==1 && opnds[5]==0 && opnds[3]==1)
05235 return TOP_c2_subs_r_w_i;
05236 else if( opnds[4]==1 && opnds[5]==1 && opnds[3]==0)
05237 return TOP_c2_sub_r_abs_h_i;
05238 else if( opnds[4]==1 && opnds[5]==1 && opnds[3]==1)
05239 return TOP_c2_sub_r_abs_w_i;
05240 else if( opnds[4]==0 && opnds[5]==0 && opnds[3]==0)
05241 return TOP_c2_subs_r_h;
05242 else if( opnds[4]==0 && opnds[5]==0 && opnds[3]==1)
05243 return TOP_c2_subs_r_w;
05244 else if( opnds[4]==0 && opnds[5]==1 && opnds[3]==0)
05245 return TOP_c2_sub_r_abs_h;
05246 else if( opnds[4]==0 && opnds[5]==1 && opnds[3]==1)
05247 return TOP_c2_sub_r_abs_w;
05248 else {
05249 FmtAssert(FALSE, ("invalid parameter in function c2_sub"));
05250 }
05251 break;
05252 case INTRN_C2_MULS:
05253 return TOP_c2_muls;
05254 case INTRN_C2_MADS:
05255 return TOP_c2_mads;
05256 break;
05257 case INTRN_C2_SMADS:
05258 return TOP_c2_smads;
05259 break;
05260 case INTRN_C2_MINMAX:
05261 if(opnds[2]==0)
05262 return TOP_c2_min;
05263 else if(opnds[2]==1)
05264 return TOP_c2_max;
05265 else {
05266 FmtAssert(FALSE, ("invalid parameter in function c2_minmax"));
05267 }
05268 break;
05269 case INTRN_C2_CMOV:
05270 return TOP_c2_cmov;
05271 case INTRN_C2_MOV:
05272 return TOP_c2_mov_g;
05273 case INTRN_C2_MOV_R:
05274 switch(opnds[4]) {
05275 case 1:
05276 return TOP_c2_mov_r;
05277 case 2:
05278 return TOP_c2_mov_c_i;
05279 case 3:
05280 return TOP_c2_mov_c;
05281 case 4:
05282 return TOP_c2_mov_s_i;
05283 case 5:
05284 return TOP_c2_mov_s;
05285 default:
05286 FmtAssert(FALSE, ("invalid parameter in function c2_mov"));
05287 }
05288 break;
05289 case INTRN_C2_CLP:
05290 if(opnds[3] == 0)
05291 return TOP_c2_clp;
05292 else if(opnds[3] == 1)
05293 return TOP_c2_clp_i;
05294 else {
05295 FmtAssert(FALSE, ("invalid parameter in function c2_clp"));
05296 }
05297 break;
05298 case INTRN_C2_CHKRNG:
05299 return TOP_c2_chkrng;
05300 break;
05301 case INTRN_C2_SCOND:
05302 if(opnds[2]==0 && opnds[3]==1)
05303 return TOP_c2_scond_eq;
05304 else if(opnds[2]==0 && opnds[3]==2)
05305 return TOP_c2_scond_lt;
05306 else if(opnds[2]==0 && opnds[3]==3)
05307 return TOP_c2_scond_le;
05308 else if( opnds[2]==0 && opnds[3]==4)
05309 return TOP_c2_scond_gt;
05310 else if( opnds[2]==0 && opnds[3]==5)
05311 return TOP_c2_scond_ge;
05312 else if( opnds[2]==1 && opnds[3]==1)
05313 return TOP_c2_scond_eq_i;
05314 else if( opnds[2]==1 && opnds[3]==2)
05315 return TOP_c2_scond_lt_i;
05316 else if( opnds[2]==1 && opnds[3]==3)
05317 return TOP_c2_scond_le_i;
05318 else if( opnds[2]==1 && opnds[3]==4)
05319 return TOP_c2_scond_gt_i;
05320 else if( opnds[2]==1 && opnds[3]==5)
05321 return TOP_c2_scond_ge_i;
05322 else {
05323 FmtAssert(FALSE, ("invalid parameter in function c2_scond"));
05324 }
05325 break;
05326 case INTRN_C2_SCOND_R:
05327 if( opnds[2]==0 && opnds[3]==1 && opnds[4] == 0)
05328 return TOP_c2_scond_r_h_eq;
05329 else if( opnds[2]==0 && opnds[3]==2 && opnds[4] == 0)
05330 return TOP_c2_scond_r_h_lt;
05331 else if( opnds[2]==0 && opnds[3]==3 && opnds[4] == 0)
05332 return TOP_c2_scond_r_h_le;
05333 else if( opnds[2]==0 && opnds[3]==4 && opnds[4] == 0)
05334 return TOP_c2_scond_r_h_gt;
05335 else if( opnds[2]==0 && opnds[3]==5 && opnds[4] == 0)
05336 return TOP_c2_scond_r_h_ge;
05337 else if( opnds[2]==1 && opnds[3]==1 && opnds[4] == 0)
05338 return TOP_c2_scond_r_h_eq_i;
05339 else if( opnds[2]==1 && opnds[3]==2 && opnds[4] == 0)
05340 return TOP_c2_scond_r_h_lt_i;
05341 else if( opnds[2]==1 && opnds[3]==3 && opnds[4] == 0)
05342 return TOP_c2_scond_r_h_le_i;
05343 else if( opnds[2]==1 && opnds[3]==4 && opnds[4] == 0)
05344 return TOP_c2_scond_r_h_gt_i;
05345 else if( opnds[2]==1 && opnds[3]==5 && opnds[4] == 0)
05346 return TOP_c2_scond_r_h_ge_i;
05347 else if( opnds[2]==0 && opnds[3]==1 && opnds[4] == 1)
05348 return TOP_c2_scond_r_w_eq;
05349 else if( opnds[2]==0 && opnds[3]==2 && opnds[4] == 1)
05350 return TOP_c2_scond_r_w_lt;
05351 else if( opnds[2]==0 && opnds[3]==3 && opnds[4] == 1)
05352 return TOP_c2_scond_r_w_le;
05353 else if( opnds[2]==0 && opnds[3]==4 && opnds[4] == 1)
05354 return TOP_c2_scond_r_w_gt;
05355 else if( opnds[2]==0 && opnds[3]==5 && opnds[4] == 1)
05356 return TOP_c2_scond_r_w_ge;
05357 else if( opnds[2]==1 && opnds[3]==1 && opnds[4] == 1)
05358 return TOP_c2_scond_r_w_eq_i;
05359 else if( opnds[2]==1 && opnds[3]==2 && opnds[4] == 1)
05360 return TOP_c2_scond_r_w_lt_i;
05361 else if( opnds[2]==1 && opnds[3]==3 && opnds[4] == 1)
05362 return TOP_c2_scond_r_w_le_i;
05363 else if( opnds[2]==1 && opnds[3]==4 && opnds[4] == 1)
05364 return TOP_c2_scond_r_w_gt_i;
05365 else if( opnds[2]==1 && opnds[3]==5 && opnds[4] == 1)
05366 return TOP_c2_scond_r_w_ge_i;
05367 else {
05368 FmtAssert(FALSE, ("invalid parameter in function c2_scond"));
05369 }
05370 break;
05371 case INTRN_C2_SCOND_R_WB:
05372 if( opnds[2]==0 && opnds[3]==1 && opnds[4] == 0)
05373 return TOP_c2_scond_r_h_wb_eq;
05374 else if( opnds[2]==0 && opnds[3]==2 && opnds[4] == 0)
05375 return TOP_c2_scond_r_h_wb_lt;
05376 else if( opnds[2]==0 && opnds[3]==3 && opnds[4] == 0)
05377 return TOP_c2_scond_r_h_wb_le;
05378 else if( opnds[2]==0 && opnds[3]==4 && opnds[4] == 0)
05379 return TOP_c2_scond_r_h_wb_gt;
05380 else if( opnds[2]==0 && opnds[3]==5 && opnds[4] == 0)
05381 return TOP_c2_scond_r_h_wb_ge;
05382 else if( opnds[2]==0 && opnds[3]==1 && opnds[4] == 1)
05383 return TOP_c2_scond_r_w_wb_eq;
05384 else if( opnds[2]==0 && opnds[3]==2 && opnds[4] == 1)
05385 return TOP_c2_scond_r_w_wb_lt;
05386 else if( opnds[2]==0 && opnds[3]==3 && opnds[4] == 1)
05387 return TOP_c2_scond_r_w_wb_le;
05388 else if( opnds[2]==0 && opnds[3]==4 && opnds[4] == 1)
05389 return TOP_c2_scond_r_w_wb_gt;
05390 else if( opnds[2]==0 && opnds[3]==5 && opnds[4] == 1)
05391 return TOP_c2_scond_r_w_wb_ge;
05392 else if( opnds[2]==1 && opnds[3]==1 && opnds[4] == 0)
05393 return TOP_c2_scond_r_wb_eq_i;
05394 else if( opnds[2]==1 && opnds[3]==2 && opnds[4] == 0)
05395 return TOP_c2_scond_r_wb_lt_i;
05396 else if( opnds[2]==1 && opnds[3]==3 && opnds[4] == 0)
05397 return TOP_c2_scond_r_wb_le_i;
05398 else if( opnds[2]==1 && opnds[3]==4 && opnds[4] == 0)
05399 return TOP_c2_scond_r_wb_gt_i;
05400 else if( opnds[2]==1 && opnds[3]==5 && opnds[4] == 0)
05401 return TOP_c2_scond_r_wb_ge_i;
05402 else if( opnds[2]==1 && opnds[3]==1 && opnds[4] == 1)
05403 return TOP_c2_scond_r_w_wb_eq_i;
05404 else if( opnds[2]==1 && opnds[3]==2 && opnds[4] == 1)
05405 return TOP_c2_scond_r_w_wb_lt_i;
05406 else if( opnds[2]==1 && opnds[3]==3 && opnds[4] == 1)
05407 return TOP_c2_scond_r_w_wb_le_i;
05408 else if( opnds[2]==1 && opnds[3]==4 && opnds[4] == 1)
05409 return TOP_c2_scond_r_w_wb_gt_i;
05410 else if( opnds[2]==1 && opnds[3]==5 && opnds[4] == 1)
05411 return TOP_c2_scond_r_w_wb_ge_i;
05412 else
05413 FmtAssert(FALSE, ("invalid parameter in function c2_scond"));
05414 break;
05415 case INTRN_C2_BOP:
05416 if(opnds[2]==0 && opnds[4]==0 && opnds[3]==1)
05417 return TOP_c2_bop_ls;
05418 else if(opnds[2]==0 && opnds[4]==0 && opnds[3]==0)
05419 return TOP_c2_bop_rs;
05420 else if(opnds[2]==0 && opnds[4]==1)
05421 return TOP_c2_bop_and;
05422 else if(opnds[2]==0 && opnds[4]==2)
05423 return TOP_c2_bop_or;
05424 else if(opnds[2]==0 && opnds[4]==3)
05425 return TOP_c2_bop_xor;
05426 else if(opnds[2]==1 && opnds[4]==0 && opnds[3]==1)
05427 return TOP_c2_bop_ls_i;
05428 else if(opnds[2]==1 && opnds[4]==0 && opnds[3]==0)
05429 return TOP_c2_bop_rs_i;
05430 else if(opnds[2]==1 && opnds[4]==1)
05431 return TOP_c2_bop_and_i;
05432 else if(opnds[2]==1 && opnds[4]==2)
05433 return TOP_c2_bop_or_i;
05434 else if(opnds[2]==1 && opnds[4]==3)
05435 return TOP_c2_bop_xor_i;
05436 else if(opnds[4] == 4)
05437 return TOP_c2_bop_andxor;
05438 else
05439 FmtAssert(FALSE, ("invalid parameter in function c2_bop"));
05440 break;
05441 case INTRN_C2_BDEP:
05442 if(opnds[3]==1)
05443 return TOP_c2_bdep_l;
05444 else if(opnds[3]==0)
05445 return TOP_c2_bdep_m;
05446 else
05447 FmtAssert(FALSE, ("invalid parameter in function c2_bdep"));
05448 break;
05449 case INTRN_C2_BXTR:
05450 if(opnds[4]==0 && opnds[3]==1)
05451 return TOP_c2_bxtr_u_l;
05452 else if(opnds[4]==1 && opnds[3]==1)
05453 return TOP_c2_bxtr_s_l;
05454 else if(opnds[4]==0 && opnds[3]==0)
05455 return TOP_c2_bxtr_u_m;
05456 else if(opnds[4]==1 && opnds[3]==0)
05457 return TOP_c2_bxtr_s_m;
05458 else
05459 FmtAssert(FALSE, ("invalid parameter in function c2_bxtr"));
05460 break;
05461 case INTRN_C2_BXTRR48:
05462 if(opnds[3] == 0)
05463 return TOP_c2_bxtrr48;
05464 else if(opnds[3] == 1)
05465 return TOP_c2_bxtrr48_i;
05466 else
05467 FmtAssert(FALSE, ("invalid parameter in function c2_bxtrr48"));
05468 case INTRN_C2_SUM4_R:
05469 if(opnds[4]==0)
05470 return TOP_c2_sum4_c;
05471 else if(opnds[4]==3)
05472 return TOP_c2_sum4_r;
05473 else
05474 FmtAssert(FALSE, ("invalid parameter in function c2_sum4"));
05475 break;
05476 case INTRN_C2_SUM4:
05477 if(opnds[2]==1)
05478 return TOP_c2_sum4_g;
05479 else if(opnds[2]==2)
05480 return TOP_c2_sum4_sw;
05481 else
05482 FmtAssert(FALSE, ("invalid parameter in function c2_sum4"));
05483 break;
05484 case INTRN_C2_SUM3_SADDR:
05485 return TOP_c2_sum4_saddr;
05486 case INTRN_C2_MED:
05487 return TOP_c2_med;
05488 case INTRN_C2_LD_V2G:
05489 if(opnds[2] >= 2 && opnds[1] == 0 )
05490 return TOP_c2_ld_v2g_b_u;
05491 else if(opnds[2] >= 2 && opnds[1] == 1 )
05492 return TOP_c2_ld_v2g_b;
05493 else if(opnds[2] == 0 && opnds[1] == 0 )
05494 return TOP_c2_ld_v2g_h_u;
05495 else if(opnds[2] == 0 && opnds[1] == 1 )
05496 return TOP_c2_ld_v2g_h;
05497 else if(opnds[2] == 1)
05498 return TOP_c2_ld_v2g_w;
05499 else
05500 FmtAssert(FALSE, ("invalid parameter in function c2_ld_v2g"));
05501 case INTRN_C2_LD_V2G_IMM:
05502 if(opnds[1] >= 2 && opnds[0] == 0)
05503 return TOP_c2_ldi_v2g_b_u;
05504 else if(opnds[1] >= 2 && opnds[0] == 1)
05505 return TOP_c2_ldi_v2g_b;
05506 else if(opnds[1] == 0 && opnds[0] == 0)
05507 return TOP_c2_ldi_v2g_h_u;
05508 else if(opnds[1] == 0 && opnds[0] == 1)
05509 return TOP_c2_ldi_v2g_h;
05510 else if(opnds[1] == 1)
05511 return TOP_c2_ldi_v2g_w;
05512 else
05513 FmtAssert(FALSE, ("invalid parameter in function c2_ld_v2g_imm"));
05514 case INTRN_C2_ST_G2V:
05515 if(opnds[2] >= 2)
05516 return TOP_c2_st_g2v_b;
05517 else if (opnds[2] == 0)
05518 return TOP_c2_st_g2v_h;
05519 else if (opnds[2] == 1)
05520 return TOP_c2_st_g2v_w;
05521 else
05522 FmtAssert(FALSE, ("invalid parameter in function c2_st_g2v"));
05523 case INTRN_C2_ST_G2V_IMM:
05524 if(opnds[1] >= 2)
05525 return TOP_c2_sti_g2v_b;
05526 else if (opnds[1] == 0)
05527 return TOP_c2_sti_g2v_h;
05528 else if (opnds[1] == 1)
05529 return TOP_c2_sti_g2v_w;
05530 else
05531 FmtAssert(FALSE, ("invalid parameter in function c2_st_g2v_imm"));
05532 case INTRN_C2_GSUMS:
05533 return TOP_c2_gsums;
05534 case INTRN_C2_WRAP:
05535 return TOP_c2_wrap;
05536 case INTRN_C2_CLZOB:
05537 if(opnds[2] == 0) {
05538 switch(opnds[3]) {
05539 case 0:
05540 return TOP_c2_clzob_zd;
05541 case 1:
05542 return TOP_c2_clzob_od;
05543 default:
05544 FmtAssert(FALSE, ("invalid parameter in function c2_clzob"));
05545 };
05546 }
05547 else if(opnds[2] == 1) {
05548 switch(opnds[3]) {
05549 case 0:
05550 return TOP_c2_clzob_zd_i;
05551 case 1:
05552 return TOP_c2_clzob_od_i;
05553 default:
05554 FmtAssert(FALSE, ("invalid parameter in function c2_clzob"));
05555 };
05556 }
05557 else
05558 FmtAssert(FALSE, ("invalid parameter in function c2_clzob"));
05559 case INTRN_C2_THCTRL:
05560 switch(opnds[0]) {
05561 case 0:
05562 return TOP_c2_thctrl_lock;
05563 case 1:
05564 return TOP_c2_thctrl_unlock;
05565 case 2:
05566 return TOP_c2_thctrl_deact;
05567 case 3:
05568 return TOP_c2_thctrl_act;
05569 case 4:
05570 return TOP_c2_thctrl_mode4;
05571 case 5:
05572 return TOP_c2_thctrl_mode5;
05573 case 6:
05574 return TOP_c2_thctrl_mode6;
05575 case 7:
05576 return TOP_c2_thctrl_mode7;
05577 default:
05578 FmtAssert(FALSE, ("invalid op_mode in function c2_thctrl"));
05579 };
05580 case INTRN_C2_JOINT:
05581 return TOP_c2_joint;
05582 case INTRN_PERIPHERAL_RW_BEGIN:
05583 return TOP_peripheral_rw_begin;
05584 case INTRN_PERIPHERAL_RW_END:
05585 return TOP_peripheral_rw_end;
05586 default:
05587 FmtAssert(FALSE, ("SL2 intrinsic NYI"));
05588 }
05589 }
05590
05591
05592
05593
05594
05595
05596
05597
05598 BOOL
05599 Need_Relocation(TOP opcode, UINT opnd_pos) {
05600 switch (opcode) {
05601 case TOP_c2_ldi_c:
05602 case TOP_c2_sti_c:
05603 if(opnd_pos == 1) return TRUE;
05604 return FALSE;
05605 case TOP_c2_sti_s_h:
05606 case TOP_c2_sti_s_w:
05607 case TOP_c2_ldi_s_h_u:
05608 case TOP_c2_ldi_s_h:
05609 case TOP_c2_ldi_s_w:
05610 case TOP_c2_ldi_v2g_b_u:
05611 case TOP_c2_ldi_v2g_b:
05612 case TOP_c2_ldi_v2g_h:
05613 case TOP_c2_ldi_v2g_h_u:
05614 case TOP_c2_ldi_v2g_w:
05615 case TOP_c2_sti_g2v_b:
05616 case TOP_c2_sti_g2v_h:
05617 case TOP_c2_sti_g2v_w:
05618 if(opnd_pos == 2) return TRUE;
05619 return FALSE;
05620 case TOP_c2_sti_v_b:
05621 case TOP_c2_sti_v_h:
05622 case TOP_c2_sti_v_w:
05623 case TOP_c2_sti_v_m_b:
05624 case TOP_c2_sti_v_m_h:
05625 case TOP_c2_sti_v_m_w:
05626 if(opnd_pos == 3) return TRUE;
05627 return FALSE;
05628 case TOP_c2_ldi_v_b_u:
05629 case TOP_c2_ldi_v_b:
05630 case TOP_c2_ldi_v_h:
05631 case TOP_c2_ldi_v_w:
05632 case TOP_c2_ldi_v_m_b_u:
05633 case TOP_c2_ldi_v_m_b:
05634 case TOP_c2_ldi_v_m_h:
05635 case TOP_c2_ldi_v_m_w:
05636 if(opnd_pos == 4) return TRUE;
05637 return FALSE;
05638 default:
05639 return FALSE;
05640 }
05641 }
05642
05643 TN_RELOCS
05644 Get_TN_Rel_From_Opcode(TOP opcode) {
05645 switch (opcode) {
05646 case TOP_c2_ldi_s_h_u:
05647 case TOP_c2_ldi_s_h:
05648 case TOP_c2_ldi_s_w:
05649 case TOP_c2_ldi_c:
05650 case TOP_c2_sti_c:
05651 case TOP_c2_sti_s_h:
05652 case TOP_c2_sti_s_w:
05653 return TN_RELOC_GPREL_S;
05654 case TOP_c2_ldi_v_b_u:
05655 case TOP_c2_ldi_v_b:
05656 case TOP_c2_ldi_v_h:
05657 case TOP_c2_ldi_v_w:
05658 case TOP_c2_ldi_v_m_b_u:
05659 case TOP_c2_ldi_v_m_b:
05660 case TOP_c2_ldi_v_m_h:
05661 case TOP_c2_ldi_v_m_w:
05662 case TOP_c2_sti_v_b:
05663 case TOP_c2_sti_v_h:
05664 case TOP_c2_sti_v_w:
05665 case TOP_c2_sti_v_m_b:
05666 case TOP_c2_sti_v_m_h:
05667 case TOP_c2_sti_v_m_w:
05668 return TN_RELOC_GPREL_SL2_V11;
05669 case TOP_c2_ldi_v2g_b_u:
05670 case TOP_c2_ldi_v2g_b:
05671 case TOP_c2_ldi_v2g_h:
05672 case TOP_c2_ldi_v2g_h_u:
05673 case TOP_c2_ldi_v2g_w:
05674 case TOP_c2_sti_g2v_b:
05675 case TOP_c2_sti_g2v_h:
05676 case TOP_c2_sti_g2v_w:
05677 return TN_RELOC_GPREL_SL2_V15;
05678 default:
05679 return TN_RELOC_NONE;
05680 }
05681 }
05682
05683
05684
05685
05686
05687 BOOL
05688 Is_SL2_Scond_With_Scalar_Destination(TOP opcode) {
05689 switch (opcode) {
05690 case TOP_c2_scond_eq:
05691 case TOP_c2_scond_lt:
05692 case TOP_c2_scond_le:
05693 case TOP_c2_scond_gt:
05694 case TOP_c2_scond_ge:
05695 case TOP_c2_scond_eq_i:
05696 case TOP_c2_scond_lt_i:
05697 case TOP_c2_scond_le_i:
05698 case TOP_c2_scond_gt_i:
05699 case TOP_c2_scond_ge_i:
05700 case TOP_c2_scond_r_h_wb_eq:
05701 case TOP_c2_scond_r_h_wb_lt:
05702 case TOP_c2_scond_r_h_wb_le:
05703 case TOP_c2_scond_r_h_wb_gt:
05704 case TOP_c2_scond_r_h_wb_ge:
05705 case TOP_c2_scond_r_wb_eq_i:
05706 case TOP_c2_scond_r_wb_lt_i:
05707 case TOP_c2_scond_r_wb_le_i:
05708 case TOP_c2_scond_r_wb_gt_i:
05709 case TOP_c2_scond_r_wb_ge_i:
05710 case TOP_c2_scond_r_w_wb_eq:
05711 case TOP_c2_scond_r_w_wb_lt:
05712 case TOP_c2_scond_r_w_wb_le:
05713 case TOP_c2_scond_r_w_wb_gt:
05714 case TOP_c2_scond_r_w_wb_ge:
05715 case TOP_c2_scond_r_w_wb_eq_i:
05716 case TOP_c2_scond_r_w_wb_lt_i:
05717 case TOP_c2_scond_r_w_wb_le_i:
05718 case TOP_c2_scond_r_w_wb_gt_i:
05719 case TOP_c2_scond_r_w_wb_ge_i:
05720 return TRUE;
05721 default:
05722 return FALSE;
05723 }
05724 }
05725
05726 BOOL
05727 Is_SL2_Scond_Without_Scalar_Destination(TOP opcode) {
05728 switch(opcode) {
05729 case TOP_c2_scond_r_h_eq:
05730 case TOP_c2_scond_r_h_lt:
05731 case TOP_c2_scond_r_h_le:
05732 case TOP_c2_scond_r_h_gt:
05733 case TOP_c2_scond_r_h_ge:
05734 case TOP_c2_scond_r_h_eq_i:
05735 case TOP_c2_scond_r_h_lt_i:
05736 case TOP_c2_scond_r_h_le_i:
05737 case TOP_c2_scond_r_h_gt_i:
05738 case TOP_c2_scond_r_h_ge_i:
05739 case TOP_c2_scond_r_w_eq:
05740 case TOP_c2_scond_r_w_lt:
05741 case TOP_c2_scond_r_w_le:
05742 case TOP_c2_scond_r_w_gt:
05743 case TOP_c2_scond_r_w_ge:
05744 case TOP_c2_scond_r_w_eq_i:
05745 case TOP_c2_scond_r_w_lt_i:
05746 case TOP_c2_scond_r_w_le_i:
05747 case TOP_c2_scond_r_w_gt_i:
05748 case TOP_c2_scond_r_w_ge_i:
05749 return TRUE;
05750 default:
05751 return FALSE;
05752 }
05753 }
05754
05755 BOOL
05756 Is_C2_Scond_Instruction(TOP opcode) {
05757 return (Is_SL2_Scond_With_Scalar_Destination(opcode) ||
05758 Is_SL2_Scond_Without_Scalar_Destination(opcode));
05759 }
05760
05761 INT32
05762 SL2_Intrn_Results_Count( INTRINSIC id) {
05763 switch(id) {
05764 case INTRN_C2_MVGR_R2G:
05765 case INTRN_C2_MVGR_S2G:
05766 case INTRN_C2_MVGC_C2G:
05767 case INTRN_C2_LD_G:
05768 case INTRN_C2_LD_V2G:
05769 case INTRN_C2_LD_V2G_IMM:
05770 case INTRN_C2_LD_G_IMM:
05771 case INTRN_C2_BCST:
05772 case INTRN_C2_ADDS:
05773 case INTRN_C2_SUBS:
05774 case INTRN_C2_MADS:
05775 case INTRN_C2_SMADS:
05776 case INTRN_C2_MINMAX:
05777 case INTRN_C2_MULS:
05778 case INTRN_C2_SUM4:
05779 case INTRN_C2_SUM3_SADDR:
05780 case INTRN_C2_MOV:
05781 case INTRN_C2_CHKRNG:
05782 case INTRN_C2_BXTR:
05783 case INTRN_C2_CMOV:
05784 case INTRN_C2_MED:
05785 case INTRN_C2_CLP:
05786 case INTRN_C2_SCOND:
05787 case INTRN_C2_SCOND_R_WB:
05788 case INTRN_C2_BOP:
05789 case INTRN_C2_SAD:
05790 case INTRN_C2_SATD:
05791 case INTRN_C2_GSUMS:
05792 case INTRN_C2_CLZOB:
05793 case INTRN_C2_WRAP:
05794 return 1;
05795 case INTRN_C2_MVSEL:
05796 case INTRN_C2_VLCS:
05797 return 2;
05798 default:
05799 return 0;
05800 }
05801 }
05802
05803
05804
05805
05806
05807
05808
05809
05810
05811
05812
05813
05814
05815
05816
05817 static
05818 int Decide_Number_Of_Multi_Mode( TN* tn_c6, OPS *ops )
05819 {
05820 int number = 31;
05821 BOOL found = FALSE;
05822
05823
05824
05825 OP *defop_c6 = NULL;
05826 OP *op = OPS_last(ops);
05827 while( op && !found ){
05828 INT32 res_num = OP_results(op);
05829 for(INT32 i=0; i < res_num; i++ ){
05830 if( TN_number(tn_c6) == TN_number(OP_result(op, i)) ){
05831 defop_c6 = op;
05832 found = TRUE;
05833 break;
05834 }
05835 }
05836 op = OP_prev(op);
05837 }
05838
05839 if( !defop_c6 || (OP_code(defop_c6) != TOP_c2_mvgc_g2c) ) {
05840 DevWarn( "In Decide_Number_Of_Multi_Mode()" );
05841 DevWarn( "Missing c2.mvgc.g2c for mutli mode c2.ld/st" );
05842 return number;
05843 }
05844
05845
05846
05847
05848 TN* tn_gpr = OP_opnd( defop_c6, 0 );
05849 if( !TN_is_register(tn_gpr) ){
05850 DevWarn( "In Decide_Number_Of_Multi_Mode()" );
05851 DevWarn( "Missing gpr in c2.mvgc.g2c for mutli mode c2.ld/st" );
05852 return number;
05853 }
05854
05855
05856 OP *defop_gpr = NULL ;
05857 found = FALSE;
05858 op = OP_prev( defop_c6 );
05859 while( op && !found ){
05860 INT32 res_num = OP_results(op);
05861 for(INT32 i=0; i < res_num; i++ ){
05862 if( TN_number(tn_gpr) == TN_number(OP_result(op, i)) ){
05863 defop_gpr = op;
05864 found = TRUE;
05865 break;
05866 }
05867 }
05868 op = OP_prev(op);
05869 }
05870
05871
05872
05873 if( !defop_gpr || (OP_code(defop_gpr) != TOP_ori) ) {
05874 DevWarn( "In Decide_Number_Of_Multi_Mode()" );
05875 DevWarn( "Missing or.i for mutli mode c2.ld/st" );
05876 return number;
05877 }
05878
05879 TN* tn_or_gpr = OP_opnd( defop_gpr, 0 );
05880 TN* tn_or_immd = OP_opnd( defop_gpr, 1 );
05881
05882
05883
05884
05885 if( !TN_is_constant(tn_or_immd) || TN_value(tn_or_immd) > 0xffff ) {
05886 DevWarn( "In Decide_Number_Of_Multi_Mode()" );
05887 DevWarn( "Missing, immediate number of or.i is not suitable for mutli mode c2.ld/st" );
05888 return number;
05889 }
05890
05891
05892 OP* defop_or_i_gpr = NULL;
05893 found = FALSE;
05894 op = OP_prev( defop_gpr );
05895 while( op && !found ){
05896 INT32 res_num = OP_results(op);
05897 for(INT32 i=0; i < res_num; i++ ){
05898 if( TN_number(tn_or_gpr) == TN_number(OP_result(op, i)) ){
05899 defop_or_i_gpr = op;
05900 found = TRUE;
05901 break;
05902 }
05903 }
05904 op = OP_prev(op);
05905 }
05906
05907 if( !defop_or_i_gpr || (OP_code(defop_or_i_gpr) != TOP_lui) ) {
05908 DevWarn( "In Decide_Number_Of_Multi_Mode()" );
05909 DevWarn( "Missing mvup.i for mutli mode c2.ld/st" );
05910 return number;
05911 }
05912
05913 TN* tn_mvup_immd = OP_opnd( defop_or_i_gpr, 0 );
05914 if( !TN_is_constant(tn_mvup_immd) ) {
05915 DevWarn( "In Decide_Number_Of_Multi_Mode()" );
05916 DevWarn( "Missing mvup.i operand is not immediate for mutli mode c2.ld/st" );
05917 return number;
05918 }
05919
05920 number = TN_value( tn_mvup_immd );
05921
05922
05923 if( number > 31 ) {
05924 DevWarn( "In Decide_Number_Of_Multi_Mode()" );
05925 DevWarn( "The multi mode number is larger than 31" );
05926 number = 31;
05927 }
05928
05929 return number;
05930 }
05931
05932
05933
05934
05935
05936
05937
05938
05939
05940 static
05941 INT Build_Multi_Mode_Ldst( OP* op, OPS *ops )
05942 {
05943
05944
05945
05946
05947
05948
05949
05950 if( op->extra_operand || op->extra_result )
05951 return 0;
05952
05953 TOP opcode = OP_code( op );
05954 TN* tn_c6;
05955
05956
05957
05958
05959
05960 int multi_num;
05961
05962
05963
05964
05965
05966
05967
05968
05969
05970
05971 tn_c6 = OP_opnd( op, TOP_Find_Operand_Use(opcode, OU_ls_ctrl));
05972 multi_num = Decide_Number_Of_Multi_Mode( tn_c6, ops );
05973 DevWarn("muti number is :%i", multi_num );
05974
05975 if( opcode == TOP_c2_ldi_v_m_w ) {
05976
05977 TN* first_dest_tn = OP_result( op, 0 );
05978 Is_True( TN_is_register(first_dest_tn), ("dest tn is not a register tn, of top_c2_ldi_v_m") );
05979 int reg_num = TN_register( first_dest_tn ) - 1;
05980 DevWarn("register number is :%i", reg_num );
05981
05982 if( 2*(multi_num+1) - 1 + reg_num > 31 ) {
05983 DevWarn( "in word size mode load, multimode number is too big" );
05984 multi_num = (32-reg_num)/2 - 1;
05985 }
05986
05987 for( int i=1; i < 2*(multi_num+1); i++ ) {
05988 TN* tn = Build_Dedicated_TN( ISA_REGISTER_CLASS_cop_vreg,
05989 reg_num+1+i,
05990 0 );
05991 op->extra_result = TN_LIST_Push( tn,
05992 op->extra_result,
05993 &MEM_pu_pool );
05994 }
05995
05996 } else if ( opcode == TOP_c2_sti_v_m_w ) {
05997
05998 TN* first_src_tn = OP_opnd( op, 0 );
05999 Is_True( TN_is_register(first_src_tn), ("source tn is not a register tn, of top_c2_sti_v_m") );
06000 int reg_num = TN_register( first_src_tn ) - 1;
06001 DevWarn("register number is :%i", reg_num );
06002
06003 if( 2*(multi_num+1)+reg_num-1 > 31 ) {
06004 DevWarn( "in word size mode store, multimode number is too big" );
06005 multi_num = (32-reg_num)/2 - 1;
06006 }
06007
06008 for( int i=1; i < 2*(multi_num+1); i++ ) {
06009 TN* tn = Build_Dedicated_TN( ISA_REGISTER_CLASS_cop_vreg,
06010 reg_num+1+i,
06011 0 );
06012 op->extra_operand = TN_LIST_Push( tn,
06013 op->extra_operand,
06014 &MEM_pu_pool );
06015 }
06016
06017 } else {
06018 if( TOP_is_c2_multi_mode_load(opcode) ) {
06019
06020 TN* first_dest_tn = OP_result( op, 0 );
06021 Is_True( TN_is_register(first_dest_tn), ("dest tn is not a register tn, of top_c2_ldi_v_m") );
06022 int reg_num = TN_register( first_dest_tn ) -1;
06023 DevWarn("register number is :%i", reg_num );
06024
06025 if( multi_num+reg_num > 31 ) {
06026 DevWarn( "in non word size mode load, multimode number > 31" );
06027 multi_num = 31 - reg_num;
06028 }
06029
06030 for( int i=1; i < multi_num+1; i++ ) {
06031 TN* tn = Build_Dedicated_TN( ISA_REGISTER_CLASS_cop_vreg,
06032 reg_num+1+i,
06033 0 );
06034 op->extra_result = TN_LIST_Push( tn,
06035 op->extra_result,
06036 &MEM_pu_pool );
06037 }
06038
06039 } else if( TOP_is_c2_multi_mode_store(opcode) ) {
06040
06041 TN* first_src_tn = OP_opnd( op, 0 );
06042 Is_True( TN_is_register(first_src_tn), ("dest tn is not a register tn, of top_c2_ldi_v_m") );
06043 int reg_num = TN_register( first_src_tn ) - 1;
06044 DevWarn("register number is :%i", reg_num );
06045
06046 if( multi_num + reg_num > 31 ) {
06047 DevWarn( "in non word size mode store, multimode number > 31" );
06048 multi_num = 31 - reg_num;
06049 }
06050
06051 for( int i=1; i < multi_num+1; i++ ) {
06052 TN* tn = Build_Dedicated_TN( ISA_REGISTER_CLASS_cop_vreg,
06053 reg_num+1+i,
06054 0 );
06055 op->extra_operand = TN_LIST_Push( tn,
06056 op->extra_operand,
06057 &MEM_pu_pool );
06058 }
06059
06060 } else
06061 Is_True(0, ("un-recognizable opcode, in Build_Multi_Mode_Ldst"));
06062 }
06063
06064 return multi_num;
06065 }
06066
06067
06068
06069
06070
06071
06072
06073
06074
06075
06076
06077
06078
06079
06080 static std::map< int, std::vector<int> > lut_table;
06081
06082 static void
06083 Build_LUT_Insn( OP* op )
06084 {
06085
06086
06087
06088
06089
06090
06091
06092 if( op->extra_operand )
06093 return;
06094
06095 static bool lut_created = false;
06096
06097
06098 if( ! lut_created ){
06099
06100 std::string filename;
06101 if (App_Name[0] == '/') {
06102 filename = App_Name;
06103 filename.append("/lut");
06104 } else {
06105 filename = (getenv("COMP_TARGET_ROOT"));
06106 Is_True( App_Name, ("In Build_LUT_Insn, app name is not specified for lut"));
06107 filename = filename + "/usr/libsl2/" + App_Name + "/lut";
06108 }
06109 std::ifstream lut_file( filename.c_str() );
06110 Is_True(lut_file, ("LUT file: %s is not set", filename.c_str()) );
06111
06112
06113 for( int i = 0; i < 512; i++ ) {
06114 char temp[1024];
06115 lut_file.getline( temp, 1024 );
06116 std::string line(temp);
06117
06118
06119 int comma = line.find(',');
06120 std::string temp_str = line.substr( 0, comma );
06121 int index = atoi( temp_str.c_str() );
06122 std::vector<int> reg_num;
06123
06124 line = line.substr( comma+1 );
06125 bool used = false;
06126
06127
06128 for( int j = 0; j < 16; j++ ){
06129 comma = line.find(',');
06130 temp_str = line.substr( 0, comma );
06131 Is_True( temp_str.length() <= 2 , ("Wrong Reg Num in LUT, in line %d", index+1));
06132 Is_True( isdigit(temp_str[0]) ||
06133 ( temp_str[0] >= 'a' && temp_str[0] <= 'f' ) ||
06134 ( temp_str[0] == 'x' || temp_str[0] == 'X' ),
06135 (" Wrong Reg Num in LUT, in line %d", index+1) );
06136 Is_True( temp_str[1] == 0 ||
06137 isdigit(temp_str[1]) ||
06138 ( temp_str[1] >= 'a' && temp_str[1] <= 'f' ),
06139 (" Wrong Reg Num in LUT, in line %d", index+1) );
06140
06141 if( temp_str[0] == 'x' ||
06142 temp_str[0] == 'X' ) {
06143
06144 reg_num.push_back(-1);
06145 } else {
06146 int reg ;
06147 if( isdigit(temp_str[0]) ) {
06148 reg = temp_str[0] - '0';
06149 } else {
06150 reg = temp_str[0] - 'a' + 10;
06151 }
06152
06153 if( temp_str.length() == 2 ) {
06154 int t2;
06155 if( isdigit(temp_str[1]) ) {
06156 t2 = temp_str[1] - '0';
06157 } else {
06158 t2 = temp_str[1] - 'a' + 10;
06159 }
06160 reg = reg*16 + t2;
06161 }
06162 Is_True( reg >= 0 && reg <= 31, ("invalid register number"));
06163
06164
06165 std::vector<int>::iterator reg_it = reg_num.begin();
06166 bool existed = false;
06167 for( ; reg_it != reg_num.end(); reg_it++ ) {
06168 if( reg == *reg_it ) {
06169 existed = true;
06170 break;
06171 }
06172 }
06173
06174
06175 if( ! existed ) {
06176 reg_num.push_back(reg);
06177 used = true;
06178 }
06179 }
06180
06181 line = line.substr( comma + 1 );
06182 }
06183
06184 if( used ){
06185 lut_table[index] = reg_num;
06186 }
06187 }
06188
06189 lut_created = true;
06190 }
06191
06192
06193 int lut_idx = -1;
06194 TN* tn;
06195 TOP opc = OP_code(op);
06196
06197 tn = OP_opnd(op, TOP_Find_Operand_Use(opc, OU_lut_idx));
06198
06199 Is_True( TN_is_constant(tn), ("not a constant tn, for lut idx"));
06200 lut_idx = TN_value( tn );
06201
06202
06203 if( lut_idx > 511 || lut_idx < 0 )
06204 return;
06205
06206
06207 std::map< int, std::vector<int> >::iterator it;
06208 it = lut_table.find( lut_idx );
06209 if( it != lut_table.end() ) {
06210
06211 std::vector<int> extra_opnds = (*it).second;
06212 std::vector<int>::iterator opnd_it = extra_opnds.begin();
06213 for( ; opnd_it != extra_opnds.end(); opnd_it++ ) {
06214 int i = *opnd_it;
06215 if( i >= 0 && i <= 31 ) {
06216 TN* tn = Build_Dedicated_TN( ISA_REGISTER_CLASS_cop_vreg,
06217 1+i, 0 );
06218 op->extra_operand = TN_LIST_Push( tn, op->extra_operand,
06219 &MEM_pu_pool );
06220 }
06221 }
06222 }
06223
06224 return;
06225 }
06226
06227
06228 inline INT64
06229 reg_num(WN* node)
06230 {
06231 return (WN_const_val(node) + REGISTER_MIN);
06232 }
06233
06234 inline INT64
06235 reg_pair_num(WN* node)
06236 {
06237 return (WN_const_val(node) + REGISTER_MIN + 1);
06238 }
06239
06240 TN*
06241 Generate_TN(TOP opcode, SL_OPND_INFO* info, WN* intrncall)
06242 {
06243 TN* tmp_tn;
06244 ST* st;
06245 INT64 ofst;
06246 WN* wn_node;
06247 OPND_ATTR_TYPE type = SL_OPND_INFO_Type(info);
06248 UINT32 pos = SL_OPND_INFO_Pos(info);
06249
06250 if(WN_kid_count(intrncall) > 0) {
06251 Is_True(pos <WN_kid_count(intrncall),
06252 ("position number greater than kids count in function Generate_TN"));
06253 wn_node = WN_kid0(WN_kid(intrncall, pos));
06254 }
06255
06256 switch(type) {
06257 case attr_undef:
06258 return NULL;
06259 case attr_lit:
06260 tmp_tn = Gen_Literal_TN(WN_const_val(wn_node), 4 );
06261 break;
06262 case attr_cop_creg:
06263 tmp_tn = Build_Dedicated_TN( ISA_REGISTER_CLASS_cop_creg,
06264 reg_num(wn_node), 0);
06265 break;
06266 case attr_cop_vreg:
06267 tmp_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_cop_vreg, reg_num(wn_node), 0);
06268 break;
06269 case attr_pair_cop_vreg:
06270 if(reg_pair_num(wn_node) > 32) {
06271 Print_Src_Line(current_srcpos, stderr);
06272 Fail_FmtAssertion("register v%d cannot have pair register", WN_const_val(wn_node));
06273 }
06274 tmp_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_cop_vreg, reg_pair_num(wn_node), 0);
06275 break;
06276 case attr_integer_reg:
06277 tmp_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
06278 break;
06279 case attr_expr:
06280 tmp_tn = Expand_Expr(wn_node, intrncall, NULL, WN_intrinsic(intrncall));
06281 break;
06282 case attr_sym:
06283 {
06284 st = WN_st(WN_kid0(WN_kid(intrncall, pos)));
06285 ofst = WN_lda_offset(WN_kid0(WN_kid(intrncall, pos)));
06286 Is_True(st, ("cannot calculate address including a variable at line %d\n",
06287 WN_linenum(intrncall)));
06288 TN_RELOCS rel_type = Get_TN_Rel_From_Opcode(opcode);
06289 tmp_tn = Gen_Symbol_TN(st, ofst, rel_type);
06290 }
06291 break;
06292 case attr_c2sum_acc:
06293 tmp_tn = sum_acc_tn;
06294 break;
06295 case attr_c2cond:
06296 tmp_tn = c2_cond_tn;
06297 break;
06298 case attr_c2mvsel_internals:
06299 tmp_tn = mvsel_internals_tn;
06300 break;
06301 case attr_c2vlcs_internals:
06302 tmp_tn = vlcs_internals_tn;
06303 break;
06304 case attr_c2movpat_internals:
06305 tmp_tn = mvpat_internals_tn;
06306 break;
06307 case attr_c2vadd_shft:
06308 tmp_tn = vadd_shft_tn;
06309 break;
06310 case attr_c2dcac_shft:
06311 tmp_tn = dcac_shft_tn;
06312 break;
06313 case attr_c2add_ctrl:
06314 tmp_tn = add_ctrl_tn;
06315 break;
06316 case attr_c2mvsel:
06317 tmp_tn = mvsel_tn;
06318 break;
06319 case attr_c2sum_ctrl:
06320 tmp_tn = sum_ctrl_tn;
06321 break;
06322 case attr_c2ls_sw:
06323 tmp_tn = ls_sw_tn;
06324 break;
06325 case attr_c2ls_ctrl:
06326 tmp_tn = ls_ctrl_tn;
06327 break;
06328 case attr_c2mult_hi:
06329 tmp_tn = mult_hi_tn;
06330 break;
06331 case attr_ofst_zero:
06332 tmp_tn = ofst_zero_tn;
06333 break;
06334 default:
06335 FmtAssert(FALSE, ("illegal opnd type in SL intrinsic expansion"));
06336 }
06337 return tmp_tn;
06338 }
06339
06340 BOOL
06341 SL2_Intrn_Has_Return( INTRINSIC id) {
06342 switch(id) {
06343 case INTRN_C2_MVGR_R2G:
06344 case INTRN_C2_MVGR_S2G:
06345 case INTRN_C2_MVGC_C2G:
06346 case INTRN_C2_LD_G:
06347 case INTRN_C2_LD_V2G:
06348 case INTRN_C2_LD_V2G_IMM:
06349 case INTRN_C2_LD_G_IMM:
06350 case INTRN_C2_BCST:
06351 case INTRN_C2_BDEP:
06352 case INTRN_C2_ADDS:
06353 case INTRN_C2_SUBS:
06354 case INTRN_C2_MADS:
06355 case INTRN_C2_SMADS:
06356 case INTRN_C2_MINMAX:
06357 case INTRN_C2_MULS:
06358 case INTRN_C2_SUM4:
06359 case INTRN_C2_SUM3_SADDR:
06360 case INTRN_C2_MOV:
06361 case INTRN_C2_CHKRNG:
06362 case INTRN_C2_BXTR:
06363 case INTRN_C2_BXTRR48:
06364 case INTRN_C2_CMOV:
06365 case INTRN_C2_MED:
06366 case INTRN_C2_CLP:
06367 case INTRN_C2_SCOND:
06368 case INTRN_C2_SCOND_R_WB:
06369 case INTRN_C2_BOP:
06370 case INTRN_C2_SAD:
06371 case INTRN_C2_SATD:
06372 case INTRN_C2_GSUMS:
06373 case INTRN_C2_CLZOB:
06374 case INTRN_C2_WRAP:
06375 case INTRN_C2_MVSEL:
06376 case INTRN_C2_VLCS:
06377 return TRUE;
06378 default:
06379 return FALSE;
06380 }
06381 }
06382
06383
06384
06385
06386
06387 TN*
06388 Build_SL_Intrinsic_OP( INTRINSIC id, WN* intrncall, OPS *ops, TN* result )
06389 {
06390 TOP opcode;
06391 UINT32 opnds[15];
06392 TN* tmp;
06393 TN* result_tn = NULL;
06394 TN* arg[15];
06395 TN* res_tn[10], *opnd_tn[10];
06396 TN_RELOCS rel_type;
06397
06398 if( id >= INTRN_SL2_BEGIN && id <= INTRN_SL2_END ) {
06399 opcode = Analyze_SL2_Intrinsic(id, intrncall);
06400 }
06401
06402 SL_INTRN_EXP_INFO * info = SL_Intrn_Info(opcode);
06403
06404 Is_True((opcode == SL_INTRN_INFO_Opcode(info)),
06405 ("Opcode and expansion information mismatch "));
06406
06407 OPNDS_INFO_IDX* res_opnd_info = SL_INTRN_INFO_Idx_Array(info);
06408
06409 UINT32 res_count = TOP_fixed_results(opcode);
06410
06411 UINT32 opnds_count = TOP_fixed_opnds(opcode);
06412
06413 for(INT32 i = 0; i < res_count; i++) {
06414 SL_OPND_INFO* info_entry = SL_Opnd_Info(SL_INTRN_INFO_Res_Opnd_Info(res_opnd_info[i]));
06415 res_tn[i] = Generate_TN(opcode, info_entry, intrncall);
06416 }
06417
06418 for(INT32 i = 0; i < opnds_count; i++) {
06419 SL_OPND_INFO* info_entry = SL_Opnd_Info(SL_INTRN_INFO_Res_Opnd_Info
06420 (res_opnd_info[i+res_count]));
06421 opnd_tn[i] = Generate_TN(opcode, info_entry, intrncall);
06422 }
06423
06424 if(WN_intrinsic(intrncall) == INTRN_C2_BDEP) {
06425 if(TN_is_zero_reg(res_tn[0])) {
06426 TN* tmp = Build_TN_Like(res_tn[0]);
06427 Build_OP(TOP_add, tmp, Zero_TN, Zero_TN, ops);
06428 res_tn[0] = tmp;
06429 }
06430
06431 opnd_tn[2] = res_tn[0];
06432 }
06433
06434 if(WN_intrinsic(intrncall) == INTRN_C2_SATD) {
06435 res_tn[2] = opnd_tn[1];
06436 }
06437
06438 OP* op = Mk_VarOP(opcode, res_count, opnds_count, res_tn, opnd_tn);
06439
06440 OPS_Append_Op(ops, op);
06441
06442
06443 if(WN_intrinsic(intrncall) == INTRN_C2_VSPEL ||
06444 WN_intrinsic(intrncall) == INTRN_C2_VSPEL_MAC) {
06445 Build_LUT_Insn(op);
06446 }
06447
06448 if( TOP_is_c2_multi_mode_load(OP_code(op)) ||
06449 TOP_is_c2_multi_mode_store(OP_code(op)) ){
06450 Build_Multi_Mode_Ldst(op, ops);
06451 }
06452
06453 if(OP_c2_load(op) || OP_c2_store(op))
06454 Set_OP_To_WN_Map(intrncall);
06455
06456 if(SL2_Intrn_Has_Return(id))
06457 result_tn = OP_result(op, 0);
06458
06459 return result_tn;
06460 }
06461
06462
06463 TN * Exp_SL_Intrinsic_Call (INTRINSIC id, WN *intrncall,
06464 OPS *ops, LABEL_IDX *label, OPS *loop_ops, TN* result_tn)
06465 {
06466 UINT32 bank, row, op_type, imm5, ext_op, c_type, sign;
06467 TN *result, *result_0, *result_1, *result_2, *result_3, *opnd_0, *opnd_1;
06468 result = NULL;
06469 if( (id >= INTRN_SL_INTRN_BGN) && (id <= INTRN_SL_INTRN_END )) {
06470 result = Build_SL_Intrinsic_OP(id, intrncall, ops, result_tn);
06471 return result;
06472 } else if ((id >= INTRN_C3_INTRINSIC_BEGIN) && (id <= INTRN_C3_INTRINSIC_END)) {
06473 result = Build_C3_Intrinsic_OP(id, intrncall, ops, result_tn);
06474 return result;
06475 } else {
06476 FmtAssert(FALSE, ("Exp_SL_Intrinsic_Call: unhandled SL intrinsic"));
06477 return NULL;
06478 }
06479 }
06480 #endif
06481
06482
06483
06484
06485
06486
06487 TN *
06488 Exp_Intrinsic_Call (INTRINSIC id, TN *op0, TN *op1, TN *op2, OPS *ops,
06489 LABEL_IDX *label, OPS *loop_ops)
06490 {
06491 switch (id) {
06492 case INTRN_APPLY_ARGS:
06493 {
06494 static ST *last_PU = NULL;
06495 static TN *return_tn;
06496 ST *current_pu_st = Get_Current_PU_ST();
06497 if (last_PU == current_pu_st)
06498 return return_tn;
06499 else {
06500 Generate_Temp_Apply_Arg();
06501 last_PU = current_pu_st;
06502 INT par;
06503 INT ofst = 16;
06504 TN *ded_tn;
06505
06506
06507
06508 TN *vararg_ptr_tn = Build_TN_Of_Mtype(MTYPE_I8);
06509 Build_OP(TOP_addiu, vararg_ptr_tn, FP_TN, Gen_Literal_TN(-56, 4), ops);
06510 Exp_Store (MTYPE_I4, vararg_ptr_tn, tmp_apply_arg, 8, ops, 0);
06511
06512
06513 for (par = 0; par < MAX_NUMBER_OF_REGISTER_PARAMETERS; par ++) {
06514 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_integer,
06515 par+5,
06516 8 );
06517 Exp_Store (MTYPE_I8, ded_tn, tmp_apply_arg, ofst, ops, 0);
06518 ofst+= 8;
06519 }
06520 for (par = 0; par < MAX_NUMBER_OF_REGISTER_PARAMETERS; par ++) {
06521 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_float,
06522 par+13,
06523 8 );
06524 Exp_Store (MTYPE_F8, ded_tn, tmp_apply_arg, ofst, ops, 0);
06525 ofst+= 8;
06526 }
06527
06528
06529 return_tn = Build_TN_Of_Mtype(MTYPE_I8);
06530 TN *base_tn, *ofst_tn;
06531 base_tn = FP_TN;
06532 ofst_tn = Gen_Symbol_TN (tmp_apply_arg, 8, 0);
06533 Exp_OP2( Pointer_Size == 4 ? OPC_I4ADD : OPC_I8ADD,
06534 return_tn, base_tn, ofst_tn, ops );
06535
06536
06537
06538
06539 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_integer, 5,
06540 8 );
06541 Exp_Store (MTYPE_I4, ded_tn, tmp_apply_arg, 0, ops, 0);
06542 return return_tn;
06543 }
06544 }
06545 case INTRN_APPLY:
06546 {
06547 if (CG_opt_level > 0) {
06548 char asm_string[256];
06549 sprintf(asm_string, "__asm_builtin_apply_load");
06550 TN *opnd[1];
06551 opnd[0] = op1;
06552 OP *asm_op = Mk_VarOP(TOP_asm, 0, 1, NULL, opnd);
06553 Set_OP_volatile(asm_op);
06554 ASM_OP_ANNOT* asm_info = TYPE_PU_ALLOC(ASM_OP_ANNOT);
06555 bzero(asm_info, sizeof(ASM_OP_ANNOT));
06556 WN *asm_wn = WN_CreateAsm_Stmt (0, asm_string);
06557 ASM_OP_wn(asm_info) = asm_wn;
06558 OP_MAP_Set(OP_Asm_Map, asm_op, asm_info);
06559 OPS_Append_Op(ops, asm_op);
06560 } else {
06561 INT par;
06562 INT ofst = 8;
06563 TN *ded_tn;
06564 for (par = 0; par < MAX_NUMBER_OF_REGISTER_PARAMETERS; par ++) {
06565 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_integer,
06566 par+5,
06567 8 );
06568 Build_OP(TOP_ld, ded_tn, op1, Gen_Literal_TN(ofst, 4), ops);
06569 ofst+= 8;
06570 }
06571 for (par = 0; par < MAX_NUMBER_OF_REGISTER_PARAMETERS; par ++) {
06572 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_float,
06573 par+13,
06574 8 );
06575 Build_OP(TOP_ldc1, ded_tn, op1, Gen_Literal_TN(ofst, 4), ops);
06576 ofst+= 8;
06577 }
06578 }
06579 return NULL;
06580 }
06581 case INTRN_RETURN:
06582 {
06583 TN *ded_tn;
06584 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_integer,
06585 3, 8);
06586 Build_OP(TOP_ld, ded_tn, op0, Gen_Literal_TN(0, 4), ops);
06587 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_float,
06588 1, 8);
06589 Build_OP(TOP_ldc1, ded_tn, op0, Gen_Literal_TN(8, 4), ops);
06590 return NULL;
06591 }
06592 return NULL;
06593 default:
06594 FmtAssert(FALSE, ("Exp_Intrinsic_Call NYI"));
06595 return NULL;
06596 }
06597 }
06598
06599
06600
06601
06602
06603
06604
06605
06606 void Exp_Simulated_Op(const OP *op, OPS *ops, INT pc_value)
06607 {
06608 TOP top = OP_code(op);
06609
06610 switch (top)
06611 {
06612 default:
06613 FmtAssert(FALSE, ("simulated OP %s not handled", TOP_Name(top)));
06614 }
06615 }
06616
06617
06618
06619
06620
06621
06622
06623 INT
06624 Simulated_Op_Real_Ops(const OP *op)
06625 {
06626 switch (OP_code(op)) {
06627 case TOP_intrncall:
06628 return Expand_TOP_intrncall (op, NULL, TRUE, 0);
06629 case TOP_spadjust:
06630 return 1;
06631 default:
06632
06633
06634
06635
06636
06637 return 0;
06638 }
06639 }
06640
06641
06642
06643
06644
06645
06646
06647
06648 INT
06649 Simulated_Op_Real_Inst_Words(const OP *op)
06650 {
06651 INT num_bytes = 0;
06652 TOP top = OP_code(op);
06653
06654 switch (top)
06655 {
06656 case TOP_spadjust:
06657 return 1;
06658 case TOP_asm:
06659 #ifdef TARG_SL
06660
06661 if (CG_check_quadword) {
06662 extern int Compute_Asm_Num (const char *asm_string, BOOL emit_phase) ;
06663 extern char* Generate_Asm_String(OP* asm_op, BB *bb);
06664 Is_True(((OP *)op)->bb, ("Simulated_Op_Real_Inst_Words:: bb is null"));
06665 char *asm_string = Generate_Asm_String((OP *)op, op->bb);
06666 num_bytes = Compute_Asm_Num((const char *)asm_string, FALSE);
06667 if (0) {
06668 fprintf(stdout, "%s --%d\n", asm_string, num_bytes);
06669 }
06670 } else {
06671 num_bytes = 3;
06672 }
06673
06674 #else
06675
06676
06677 num_bytes = 3;
06678 #endif
06679 break;
06680
06681 default:
06682 FmtAssert(FALSE, ("simulated OP %s not handled", TOP_Name(OP_code(op))));
06683 }
06684
06685 return num_bytes;
06686 }
06687
06688
06689
06690
06691
06692
06693
06694
06695 BOOL
06696 Exp_Is_Large_Stack_Sym(ST* sym, INT64 ofst)
06697 {
06698 ST *base_sym;
06699 INT64 base_ofst;
06700
06701 if (sym == NULL)
06702 return FALSE;
06703
06704 Allocate_Object(sym);
06705 Base_Symbol_And_Offset_For_Addressing (sym, ofst, &base_sym, &base_ofst);
06706
06707
06708
06709
06710 if ((base_sym == SP_Sym || base_sym == FP_Sym) &&
06711 !ISA_LC_Value_In_Class(base_ofst, LC_simm16)) {
06712 return TRUE;
06713 }
06714
06715 return FALSE;
06716 }
06717
06718 void
06719 Exp_Noop (OPS *ops)
06720 {
06721 Build_OP (CGTARG_Noop_Top(), ops);
06722 }
06723
06724 void Expand_Const (TN *dest, TN *src, TYPE_ID mtype, OPS *ops)
06725 {
06726 FmtAssert( TN_is_symbol(src), ("Expand_Const: src not a symbol TN"));
06727
06728 TCON tcon = STC_val(TN_var(src));
06729 if (TCON_ty(tcon) == MTYPE_F4) {
06730 if (TCON_fval(tcon) == 0.0) {
06731 Build_OP(TOP_or, dest, Zero_TN, Zero_TN, ops);
06732 return;
06733 }
06734 } else if (TCON_ty(tcon) == MTYPE_F8) {
06735 if (TCON_dval(tcon) == 0.0) {
06736 Build_OP(TOP_or, dest, Zero_TN, Zero_TN, ops);
06737
06738 TN *pair = Get_TN_Pair(dest);
06739 if (pair != NULL) {
06740 Build_OP(TOP_or, pair, Zero_TN, Zero_TN, ops);
06741 }
06742 return;
06743 }
06744 }
06745 Exp_Load(mtype, mtype, dest, TN_var(src), 0, ops, 0);
06746 }
06747
06748 static BB* last_bb = NULL;
06749 static TN *last_true_tn = NULL, *last_false_tn = NULL;
06750 void
06751 HB_Reinit_Pred ()
06752 {
06753 last_true_tn = NULL;
06754 last_false_tn = NULL;
06755 last_bb = NULL;
06756 }
06757
06758 void
06759 Exp_True_False_Preds_For_Block(BB *bb, TN* &true_tn, TN * &false_tn)
06760 {
06761 if (last_bb != bb)
06762 last_bb = bb;
06763 else {
06764 true_tn = last_true_tn;
06765 false_tn = last_false_tn;
06766 return;
06767 }
06768 OP* br_op = BB_branch_op(bb);
06769 if (!br_op)
06770 return;
06771 if (OP_code(br_op) == TOP_beq || OP_code(br_op) == TOP_bne) {
06772 OPS new_ops;
06773 OPS_Init(&new_ops);
06774 true_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
06775 false_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
06776 TN *tmp_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
06777 TN *tmp1_tn;
06778 Build_OP(TOP_xor, tmp_tn, OP_opnd(br_op, 0), OP_opnd(br_op, 1),
06779 &new_ops);
06780 Build_OP(TOP_sltiu, false_tn, tmp_tn, Gen_Literal_TN(1, 4), &new_ops);
06781 Build_OP(TOP_sltu, true_tn, Zero_TN, tmp_tn, &new_ops);
06782 if (OP_code(br_op) == TOP_bne) {
06783 tmp1_tn = true_tn;
06784 true_tn = false_tn;
06785 false_tn = tmp1_tn;
06786 }
06787 BB_Insert_Ops_Before(bb, br_op, &new_ops);
06788 last_true_tn = true_tn;
06789 last_false_tn = false_tn;
06790 return;
06791 } else if (OP_code(br_op) == TOP_bc1f || OP_code(br_op) == TOP_bc1t) {
06792 OPS new_ops;
06793 OPS_Init(&new_ops);
06794 true_tn = OP_opnd(br_op, 0);
06795 false_tn = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 4);
06796
06797
06798 OP *op;
06799 BOOL found_cond_set = FALSE;
06800 FOR_ALL_BB_OPs_REV(bb,op) {
06801 if (OP_results(op) &&
06802 (OP_result(op, 0) == OP_opnd(br_op, 0))) {
06803 found_cond_set = TRUE;
06804 break;
06805 }
06806 }
06807 FmtAssert((found_cond_set==TRUE),
06808 ("Did not find instruction setting condition bit in BB"));
06809 switch (OP_code(op)) {
06810 case TOP_c_le_d:
06811 Build_OP(TOP_c_lt_d, false_tn, OP_opnd(op, 1), OP_opnd(op, 0), &new_ops);
06812 break;
06813 case TOP_c_le_s:
06814 #if defined(TARG_SL)
06815 Build_OP(TOP_c_olt_s, false_tn, OP_opnd(op, 1), OP_opnd(op, 0), &new_ops);
06816 #else
06817 Build_OP(TOP_c_lt_s, false_tn, OP_opnd(op, 1), OP_opnd(op, 0), &new_ops);
06818 #endif
06819 break;
06820 case TOP_c_lt_d:
06821 Build_OP(TOP_c_le_d, false_tn, OP_opnd(op, 1), OP_opnd(op, 0), &new_ops);
06822 break;
06823 case TOP_c_lt_s:
06824 #if defined(TARG_SL)
06825 Build_OP(TOP_c_ole_s, false_tn, OP_opnd(op, 1), OP_opnd(op, 0), &new_ops);
06826 #else
06827 Build_OP(TOP_c_le_s, false_tn, OP_opnd(op, 1), OP_opnd(op, 0), &new_ops);
06828 #endif
06829 break;
06830 case TOP_c_eq_d:
06831 Build_OP(TOP_c_neq_d, false_tn, OP_opnd(op, 1), OP_opnd(op, 0),
06832 &new_ops);
06833 break;
06834 case TOP_c_eq_s:
06835 Build_OP(TOP_c_neq_s, false_tn, OP_opnd(op, 1), OP_opnd(op, 0),
06836 &new_ops);
06837 break;
06838 default:
06839 FmtAssert(FALSE, ("Handle this case"));
06840 break;
06841 }
06842 TN *tmp_tn = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 4);
06843 if (OP_code(br_op) == TOP_bc1t) {
06844 tmp_tn = true_tn;
06845 true_tn = false_tn;
06846 false_tn = tmp_tn;
06847 }
06848 BB_Insert_Ops_Before(bb, br_op, &new_ops);
06849 last_true_tn = true_tn;
06850 last_false_tn = false_tn;
06851 return;
06852 } else if (OP_code(br_op) == TOP_bgez || OP_code(br_op) == TOP_bltz) {
06853 OPS new_ops;
06854 OPS_Init(&new_ops);
06855 true_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
06856 false_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
06857 TN *tmp_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
06858 TN *tmp1_tn;
06859 Build_OP(TOP_slt, tmp_tn, OP_opnd(br_op, 0), Zero_TN,
06860 &new_ops);
06861 Build_OP(TOP_xori, true_tn, tmp_tn, Gen_Literal_TN(1, 4), &new_ops);
06862 Build_OP(TOP_slti, false_tn, OP_opnd(br_op, 0), Gen_Literal_TN(0, 4),
06863 &new_ops);
06864 if (OP_code(br_op) == TOP_bgez) {
06865 tmp1_tn = true_tn;
06866 true_tn = false_tn;
06867 false_tn = tmp1_tn;
06868 }
06869 BB_Insert_Ops_Before(bb, br_op, &new_ops);
06870 last_true_tn = true_tn;
06871 last_false_tn = false_tn;
06872 return;
06873 }
06874 FmtAssert(FALSE, ("HANDLE THIS CASE"));
06875 true_tn = false_tn = Zero_TN;
06876 }
06877
06878 BOOL
06879 Target_Has_Immediate_Operand (WN *parent, WN *expr)
06880 {
06881 OPERATOR opr = WN_operator(parent);
06882 return opr == OPR_ADD || opr == OPR_SUB ||
06883 opr == OPR_BAND || opr == OPR_BIOR || opr == OPR_BXOR ||
06884 opr == OPR_LT || opr == OPR_LE || opr == OPR_GT || opr == OPR_GE ||
06885 opr == OPR_LSHR || opr == OPR_ASHR || opr == OPR_SHL;
06886 }
06887
06888 void
06889 Exp_Spadjust (TN *dest, TN *size, VARIANT variant, OPS *ops)
06890 {
06891 Build_OP (TOP_spadjust, dest, SP_TN, size, ops);
06892 OP_variant(OPS_last(ops)) = variant;
06893 }
06894
06895
06896 char *
06897 Exp_Unique_Literal_Name (void)
06898 {
06899 static int unique;
06900 static char name[32];
06901
06902 sprintf(name, ".LC%d", unique);
06903 unique++;
06904 return name;
06905 }
06906
06907 void
06908 Exp_Generic_Pred_Calc(TN* result1, TN *result2, COMPARE_TYPE ctype,
06909 TN *qual_pred, OPS* ops)
06910 { FmtAssert(FALSE,("Unimplemented")); }
06911
06912
06913 void
06914 Exp_Pred_Calc(TN* result, OP* cmp_op, COMPARE_TYPE ctype, BOOL false_result,
06915 OPS* ops)
06916 { FmtAssert(FALSE,("Unimplemented")); }