00001 #define __STDC_LIMIT_MACROS
00002 #include <stdint.h>
00003 #include "defs.h"
00004 #include "config.h"
00005
00006 #include "util.h"
00007 #include "tn.h"
00008 #include "cg_flags.h"
00009 #include "bb.h"
00010 #include "symtab.h"
00011 #include "opcode.h"
00012 #include "const.h"
00013 #include "targ_const.h"
00014 #include "op.h"
00015 #include "cgexp.h"
00016 #include "w2op.h"
00017 #include "cgtarget.h"
00018 #include "whirl2ops.h"
00019 #include "printsrc.h"
00020 #ifdef TARG_SL
00021 #include <map>
00022 using std::map;
00023 #include "be_symtab.h"
00024 static BOOL dotrace = FALSE;
00025 #define TFile stdout
00026
00027 #include "targ_const_private.h"
00028 #endif
00029
00030 extern std::map<INT32, TN*> var2acc;
00031 extern std::map<INT32, TN*> var2addr;
00032 extern INT32 AccPregN;
00033 extern INT32 AddPregN;
00034 extern void Set_OP_To_WN_Map(WN *wn);
00035 extern void Expand_Add (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops);
00036 extern INT32 CG_Max_Accreg;
00037 extern INT32 CG_Max_Addreg;
00038 UINT16 prev_alloc_AccIndex = 0;
00039 UINT16 prev_alloc_AddrIndex = 0;
00040
00041
00042 void Print_Acc (TN *acctn) {
00043 typedef std::map<INT32, TN*> Var2Acc;
00044 Var2Acc::iterator it = var2acc.begin();
00045 fprintf(TFile, "ACC[%d] --> ", (TN_number(acctn) - 271));
00046 for(;it != var2acc.end();++it) {
00047 if ((*it).second == acctn) {
00048 if ((*it).first >= 0)
00049 fprintf(TFile, " GPR[%d] ", (*it).first);
00050 else
00051 fprintf(TFile, " ST [%s] ", ST_name(-(*it).first));
00052 }
00053 }
00054 fprintf(stdout, "\n");
00055 }
00056
00057
00058 void Print_Addr (TN *addrtn) {
00059 typedef std::map<INT32, TN*> Var2Addr;
00060 Var2Addr::iterator it = var2addr.begin();
00061 fprintf(TFile, "ADDR[%d] --> ", (TN_number(addrtn) - 275));
00062 for(;it != var2addr.end();++it)
00063 {
00064 if ((*it).second == addrtn) {
00065 if ((*it).first >= 0)
00066 fprintf(TFile, " GPR[%d] ", (*it).first);
00067 else
00068 fprintf(TFile, " ST [%s] ", ST_name(-(*it).first));
00069 }
00070 }
00071 fprintf(stdout, "\n");
00072 }
00073
00074
00075 void Initial_var2spe() {
00076 if (var2acc.size() > 0) {
00077 typedef std::map<INT32, TN*> Var2Acc;
00078 Var2Acc::iterator it = var2acc.begin();
00079 for(;it != var2acc.end();++it)
00080 {
00081 var2acc.erase((*it).first);
00082 }
00083 }
00084 if (var2addr.size() > 0) {
00085 typedef std::map<INT32, TN*> Var2Addr;
00086 Var2Addr::iterator it = var2addr.begin();
00087 for(;it != var2addr.end();++it)
00088 {
00089 var2addr.erase((*it).first);
00090 }
00091 }
00092 return;
00093 }
00094
00095 static BOOL Has_VarWN_idx(WN *stmt) {
00096 Is_True(WN_operator(stmt) == OPR_STID, ("statement should be stid "));
00097 if (WN_class(stmt) == CLASS_PREG) {
00098 if (WN_operator(stmt) == OPR_STID) {
00099 return TRUE;
00100 }
00101 } else if (WN_class(stmt) == CLASS_VAR) {
00102 return TRUE;
00103 }
00104 return FALSE;
00105 }
00106
00107
00108
00109
00110
00111 static INT Get_VarWN_idx (WN *stmt) {
00112
00113 Is_True(WN_operator(stmt) == OPR_STID || WN_operator(stmt) == OPR_LDID, ("stid or ldid"));
00114
00115 if (WN_class(stmt) == CLASS_PREG) {
00116 if (WN_operator(stmt) == OPR_STID )
00117 return WN_store_offset(stmt);
00118 else if (WN_operator(stmt) == OPR_LDID)
00119 return WN_load_offset(stmt);
00120 } else if (WN_class(stmt) == CLASS_VAR) {
00121 return (-WN_st_idx(stmt));
00122 } else {
00123 Is_True(0, ("NYI"));
00124 }
00125 }
00126
00127
00128
00129
00130 void Set_IntrnOP_Result (WN *stid) {
00131 if (WN_operator(WN_kid0(stid)) == OPR_INTRINSIC_OP ) {
00132 INTRINSIC id = (INTRINSIC) WN_intrinsic (WN_kid0(stid));
00133
00134 if (id >= INTRN_C3_INTRINSIC_BEGIN && id <= INTRN_C3_INTRINSIC_END) {
00135 if (id == INTRN_C3_PTR)
00136 AddPregN = Get_VarWN_idx(stid);
00137 else
00138 AccPregN = Get_VarWN_idx(stid);
00139 }
00140 }
00141 return;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 TN *Get_Liternal_TN (WN *wn, INT size) {
00153 INT val=0;
00154 if (WN_operator(wn) == OPR_INTCONST) {
00155 val = WN_const_val(wn);
00156 } else {
00157 Is_True(WN_class(wn) == CLASS_PREG, ("WN should be PREG variable"));
00158 WN *home = Preg_Home(WN_load_offset(wn));
00159 if (!home) {
00160 Is_True(0, ("WN should be immediate"));
00161 }
00162 Is_True(WN_operator(home) == OPR_INTCONST, ("WN should be immediate"));
00163 val = WN_const_val(home);
00164 }
00165 return Gen_Literal_TN(val, size);
00166 }
00167
00168
00169
00170 static INT TN_To_Index(TN *tn) {
00171 if (TN_is_symbol(tn)) {
00172 Is_True(TN_var(tn), ("symbol tn should have var"));
00173 return (-TN_var(tn)->st_idx);
00174 }
00175 else
00176 return TN_To_PREG(tn);
00177 }
00178
00179
00180
00181
00182
00183 void Copy_Tn_MapInfo(TN *src_tn, TN *tgt_tn) {
00184 if ( TN_register_class(tgt_tn) == TN_register_class(src_tn)) {
00185 INT32 srcpreg = TN_To_Index(src_tn);
00186 if ((var2acc.size() > 0) && var2acc[srcpreg]) {
00187 INT32 tgtpreg = TN_To_Index(tgt_tn);
00188 var2acc[tgtpreg] = var2acc[srcpreg];
00189 if (dotrace) {
00190 fprintf(TFile, "EXP_COPY::");
00191 Print_Acc(var2acc[srcpreg]);
00192 }
00193 }
00194 else if ((var2addr.size() > 0) && var2addr[srcpreg]) {
00195 INT32 tgtpreg = TN_To_Index(tgt_tn);
00196 var2addr[tgtpreg] = var2addr[srcpreg];
00197 if (dotrace) {
00198 fprintf(TFile, "EXP_COPY::");
00199 Print_Addr(var2addr[srcpreg]);
00200 }
00201 }
00202 }
00203 }
00204
00205
00206
00207
00208
00209
00210 void Copy_Preg_MapInfo(WN *stid) {
00211 WN *ldid = WN_kid0(stid);
00212 if (WN_operator(ldid) != OPR_LDID ) {
00213 return;
00214 }
00215 Is_True(WN_operator(ldid) == OPR_LDID, ("ldid"));
00216 if (!(WN_class(ldid) == CLASS_PREG) && !(WN_class(ldid) == CLASS_VAR)) {
00217 return;
00218 }
00219 INT32 srcpreg = Get_VarWN_idx(ldid);
00220
00221 INT32 tgtpreg;
00222 if (Has_VarWN_idx(stid)) {
00223 tgtpreg = Get_VarWN_idx(stid);
00224 if (var2acc[tgtpreg]) {
00225 var2acc[srcpreg] = var2acc[tgtpreg];
00226 if (dotrace) {
00227 fprintf(stdout, "HANDLE_STID::");
00228 Print_Acc(var2acc[tgtpreg]);
00229 }
00230 } else if (var2addr[tgtpreg]) {
00231 var2addr[srcpreg] = var2addr[tgtpreg];
00232 if (dotrace) {
00233 fprintf(stdout, "HANDLE_STID::");
00234 Print_Addr(var2addr[tgtpreg]);
00235 }
00236 } else if (var2acc[srcpreg]) {
00237 tgtpreg = Get_VarWN_idx(stid);
00238 var2acc[tgtpreg] = var2acc[srcpreg];
00239 if (dotrace) {
00240 fprintf(stdout, "HANDLE_STID::");
00241 Print_Acc(var2acc[srcpreg]);
00242 }
00243 } else if (var2addr[srcpreg]) {
00244 tgtpreg = Get_VarWN_idx(stid);
00245 var2addr[tgtpreg] = var2addr[srcpreg];
00246 if (dotrace) {
00247 fprintf(stdout, "HANDLE_STID::");
00248 Print_Addr(var2addr[srcpreg]);
00249 }
00250 }
00251 }
00252 }
00253
00254
00255 static INT32 Get_ParmVaridx_Intrncall(WN *intrncall, int kidnum=0) {
00256
00257 WN *para_wn = WN_kid0(WN_kid(intrncall, kidnum));
00258 OPERATOR opr = WN_operator(para_wn) ;
00259 if (opr== OPR_LDID) {
00260 return Get_VarWN_idx(para_wn);
00261 } else if (opr == OPR_INTRINSIC_OP) {
00262 INTRINSIC id = (INTRINSIC) WN_intrinsic (para_wn);
00263 if ((id >= INTRN_C3_INTRINSIC_BEGIN) && (id <= INTRN_C3_INTRINSIC_END)) {
00264 if (id == INTRN_C3_PTR)
00265 return Get_ParmVaridx_Intrncall(para_wn, 1);
00266 else
00267 return Get_ParmVaridx_Intrncall(para_wn);
00268 } else {
00269 Is_True(0, ("WN must be c3 intrinsic "));
00270 }
00271
00272 }
00273 return 0;
00274
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 static INT32 Get_ResultEqVarIdx ( WN *istore) {
00296 Is_True(WN_operator(istore) == OPR_ISTORE , ("operator must be istore")) ;
00297
00298 WN *next = WN_next(istore);
00299 INT32 varidx = Get_VarWN_idx(WN_kid1(istore));
00300 WN_OFFSET addroff = WN_offset(istore);
00301
00302 while(next) {
00303 if ((WN_operator(next) == OPR_STID) &&
00304 (WN_operator(WN_kid0(next)) == OPR_ILOAD)) {
00305 WN *load = WN_kid0(next);
00306 if ((varidx == Get_VarWN_idx(WN_kid0(load))) && (addroff == WN_offset(load)))
00307 return Get_VarWN_idx(next);
00308 }
00309 next = WN_next(next);
00310 }
00311
00312 if (!next) {
00313 if (WN_operator(WN_kid0(istore)) == OPR_LDID) {
00314 return Get_VarWN_idx(WN_kid0(istore));
00315 } else {
00316 DevWarn("init special register is undefined");
00317 return -1;
00318 }
00319 }
00320
00321 }
00322
00323 static INT32 Get_Resultidx_Intrncall (WN *intrncall) {
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 WN *next= WN_next(intrncall);
00334 WN *retval = WN_kid0(next);
00335
00336 Is_True(next && (WN_operator(next) == OPR_STID),
00337 ("intrnsic call should have result"));
00338 Is_True((WN_operator(retval) == OPR_LDID) && (ST_class(WN_st(retval)) == CLASS_PREG) &&
00339 (WN_offset(retval) == First_Int_Preg_Return_Offset),
00340 ("intrnsic call should have result tn"));
00341
00342
00343
00344 INT32 tmp_idx = Get_VarWN_idx(next);
00345
00346 if (strcmp(ST_name(WN_st(next)) , "__comma") != 0) {
00347 next = WN_next(next);
00348 }
00349
00350 while (next) {
00351 if (WN_operator(next) == OPR_STID &&
00352 (WN_operator(WN_kid0(next))==OPR_LDID) &&
00353 (tmp_idx == Get_VarWN_idx(WN_kid0(next)))) {
00354 PREG_NUM tmppn= Get_VarWN_idx(next);
00355 if (tmppn > 11 || tmppn < 4)
00356 break;
00357 }
00358 if (WN_operator(next) == OPR_ISTORE &&
00359 (WN_operator(WN_kid0(next)) == OPR_LDID) &&
00360 (tmp_idx == Get_VarWN_idx(WN_kid0(next)))) {
00361 return Get_ResultEqVarIdx(next);
00362 }
00363 next = WN_next(next);
00364 }
00365 if (!next) {
00366 return tmp_idx;
00367 }
00368
00369 return Get_VarWN_idx(next);
00370
00371 }
00372
00373
00374 static TN *Get_New_AccTN () {
00375 TN *acctn=NULL;
00376 int i;
00377 for(i = prev_alloc_AccIndex; i < (prev_alloc_AccIndex + CG_Max_Accreg); i++) {
00378 if (ACCreg[i%CG_Max_Accreg] == 0) {
00379 switch (i%CG_Max_Accreg) {
00380 case 0 : acctn = Acc0_TN ; ACCreg[0]=1; break;
00381 case 1 : acctn = Acc1_TN ; ACCreg[1]=1; break;
00382 case 2 : acctn = Acc2_TN ; ACCreg[2]=1; break;
00383 case 3 : acctn = Acc3_TN; ACCreg[3]=1; break;
00384 default: Is_True(0,("illegal acc register tn"));
00385 }
00386 }
00387 if (acctn) break;
00388 }
00389
00390 if (i == (prev_alloc_AccIndex + CG_Max_Accreg))
00391 Is_True(0, ("No valid new acc register, max acc register numbers is %d\n", CG_Max_Accreg));
00392 if (CG_round_spreg)
00393 prev_alloc_AccIndex = (i+1)%CG_Max_Accreg;
00394 return acctn;
00395 }
00396
00397 static TN *Create_Var2Acc_Map(INT32 varidx) {
00398 INT i;
00399 TN *acctn = NULL;
00400 if (var2acc.size() > 0)
00401 acctn = var2acc[varidx];
00402
00403 Is_True(!acctn, ("variable has acquired an acc register and did't free it"));
00404 acctn = Get_New_AccTN();
00405 var2acc[varidx] = acctn;
00406
00407 if (dotrace) {
00408 fprintf(TFile, "Create_Var2Acc_Map::");
00409 Print_Acc(acctn);
00410 }
00411 return acctn;
00412 }
00413
00414
00415 static TN *Get_New_DualAccTN () {
00416 TN *acctn=NULL;
00417 int i;
00418 if (prev_alloc_AccIndex %2 !=0 ) {
00419 prev_alloc_AccIndex = (prev_alloc_AccIndex+1)%CG_Max_Accreg;
00420 }
00421 for(i = prev_alloc_AccIndex; i < (prev_alloc_AccIndex + CG_Max_Accreg); i=i+2) {
00422 if ((ACCreg[i%CG_Max_Accreg] == 0) && (ACCreg[(i+1)%CG_Max_Accreg] == 0)) {
00423 switch (i%CG_Max_Accreg) {
00424 case 0 : acctn = Acc0_TN ; ACCreg[0]=1; ACCreg[1]=1;break;
00425 case 2 : acctn = Acc2_TN ; ACCreg[2]=1; ACCreg[3]=1; break;
00426 default: Is_True(0,("Get_New_DualAccTN::illegal acc register tn"));
00427 }
00428 }
00429 if (acctn) break;
00430 }
00431
00432 if (!acctn || (CG_Max_Accreg < 2) || (CG_Max_Accreg == 3 && ACCreg[3]==1))
00433 Is_True(0, ("NO valid dual acc registers, max acc register numbers are %d\n", CG_Max_Accreg));
00434
00435 if (CG_round_spreg)
00436 prev_alloc_AccIndex = (i+2)%CG_Max_Accreg;
00437
00438 return acctn;
00439 }
00440
00441 static TN *Create_Var2DualAcc_Map(INT32 varidx) {
00442 INT i;
00443 TN *acctn = NULL;
00444 if(var2acc.size() > 0)
00445 acctn = var2acc[varidx];
00446 Is_True(!acctn, ("variable has acquired an acc register and didn't free it"));
00447 acctn = Get_New_DualAccTN();
00448 var2acc[varidx] = acctn;
00449
00450 if (dotrace) {
00451 fprintf(TFile, "Create_Var2DAcc_Map::");
00452 Print_Acc(acctn);
00453 }
00454 return acctn;
00455 }
00456
00457 static TN *Get_New_AddrTN () {
00458 TN *addtn=NULL;
00459 int i;
00460 for(i = prev_alloc_AddrIndex; i < (prev_alloc_AddrIndex + CG_Max_Addreg); i++) {
00461 if (Addreg[i%CG_Max_Addreg] == 0) {
00462 switch (i%CG_Max_Addreg) {
00463 case 0 : addtn = Addr0_TN ; Addreg[0]=1; break;
00464 case 1 : addtn = Addr1_TN ; Addreg[1]=1; break;
00465 case 2 : addtn = Addr2_TN ; Addreg[2]=1; break;
00466 case 3 : addtn = Addr3_TN; Addreg[3]=1; break;
00467 case 4 : addtn = Addr4_TN; Addreg[4]=1; break;
00468 case 5 : addtn = Addr5_TN; Addreg[5]=1; break;
00469 case 6 : addtn = Addr6_TN; Addreg[6]=1; break;
00470 case 7 : addtn = Addr7_TN; Addreg[7]=1; break;
00471 default: Is_True(0,("illegal address register tn"));
00472 }
00473 }
00474 if (addtn) break;
00475 }
00476
00477 if (i == (prev_alloc_AddrIndex + CG_Max_Addreg))
00478 Is_True(0, ("No valid new address register, max address register numbers is %d\n", CG_Max_Addreg));
00479 if (CG_round_spreg)
00480 prev_alloc_AddrIndex = (i+1)%CG_Max_Addreg;
00481 return addtn;
00482 }
00483
00484 static TN * Get_AddrSize_Reg(TN *addrtn) {
00485 TN *addr_size = NULL;
00486
00487 if (addrtn == Addr0_TN)
00488 addr_size = Addrsize0_TN;
00489 else if (addrtn == Addr1_TN)
00490 addr_size = Addrsize1_TN;
00491 else if (addrtn == Addr2_TN)
00492 addr_size = Addrsize2_TN;
00493 else if (addrtn == Addr3_TN)
00494 addr_size = Addrsize3_TN;
00495 else if (addrtn == Addr4_TN)
00496 addr_size = Addrsize4_TN;
00497 else if (addrtn == Addr5_TN)
00498 addr_size = Addrsize5_TN;
00499 else if (addrtn == Addr6_TN)
00500 addr_size = Addrsize6_TN;
00501 else if (addrtn == Addr7_TN)
00502 addr_size = Addrsize7_TN;
00503 return addr_size;
00504 }
00505
00506 static TN *Create_Var2Add_Map(INT32 varidx) {
00507 INT i;
00508 TN *addrtn = NULL;
00509 if(var2addr.size() > 0)
00510 addrtn = var2addr[varidx];
00511
00512 Is_True(!addrtn, ("addrtn should be null"));
00513 addrtn = Get_New_AddrTN();
00514 var2addr[varidx] = addrtn;
00515 if(dotrace) {
00516 fprintf(TFile, "Create_Var2Add_Map::");
00517 Print_Addr(addrtn);
00518 }
00519 return addrtn;
00520 }
00521
00522 static inline void Set_Var_AccTN ( INT32 varidx, TN *acctn) {
00523 var2acc[varidx] = acctn;
00524 if (dotrace) {
00525 Print_Acc(acctn);
00526 }
00527 }
00528
00529 static inline void Set_Var_AddrTN ( INT32 varidx, TN *addtn) {
00530 var2addr[varidx] = addtn;
00531 if (dotrace) {
00532 Print_Addr(addtn);
00533 }
00534 }
00535
00536
00537 static TN *Get_Acc_from_Varidx(INT32 varidx) {
00538 if ((var2acc.size() > 0) && var2acc[varidx]) {
00539 return var2acc[varidx];
00540 } else
00541 return NULL;
00542 }
00543
00544 static TN *Get_Addr_from_Varidx(INT32 varidx) {
00545 if ((var2addr.size() > 0) && var2addr[varidx]) {
00546 return var2addr[varidx];
00547 }
00548 else
00549 return NULL;
00550 }
00551
00552 static void Erase_AccTN (TN *acctn) {
00553 if (acctn == Acc0_TN)
00554 ACCreg[0] = 0;
00555 else if (acctn == Acc1_TN)
00556 ACCreg[1] = 0;
00557 else if (acctn == Acc2_TN)
00558 ACCreg[2] = 0;
00559 else if (acctn == Acc3_TN)
00560 ACCreg[3] = 0;
00561 else
00562 Is_True(0, ("tn is not a valie acc register tn"));
00563
00564 return;
00565 }
00566
00567
00568 static void Erase_Var2Acc_Map(INT32 varidx) {
00569 TN *acctn = Get_Acc_from_Varidx(varidx);
00570 Is_True(acctn, ("acctn are not used or has been freed before "));
00571
00572 if(dotrace) {
00573 fprintf(TFile, "Erase_Var2Acc_Map:: ");
00574 Print_Acc(acctn);
00575 }
00576 Erase_AccTN(acctn);
00577
00578 typedef std::map<INT32, TN*> Var2Acc;
00579 Var2Acc::iterator it = var2acc.begin();
00580 for(;it != var2acc.end();++it)
00581 {
00582 if ((*it).second == acctn) {
00583 var2acc.erase((*it).first);
00584 }
00585 }
00586 return;
00587 }
00588
00589
00590
00591
00592 static TN *Get_DualAccTN (TN *acc_tn) {
00593 TN *dacc_tn ;
00594 if (acc_tn == Acc0_TN)
00595 dacc_tn = Acc1_TN;
00596 else if (acc_tn == Acc2_TN)
00597 dacc_tn = Acc3_TN;
00598 else if (acc_tn == Acc3_TN || acc_tn == Acc1_TN)
00599 Is_True(0, ("first dual acc register should be even index"));
00600 else {
00601 Is_True(0, ("dual acc register is not valid"));
00602 }
00603 return dacc_tn;
00604 }
00605
00606
00607 static void Erase_Var2DualAcc_Map(INT32 varidx) {
00608 TN *acctn = Get_Acc_from_Varidx(varidx);
00609 Is_True(acctn, ("dual acctn are not used or have been free before"));
00610 TN *dacctn = Get_DualAccTN(acctn);
00611
00612 if(dotrace) {
00613 fprintf(TFile, "Erase_Var2DualAcc_Map ");
00614 Print_Acc(acctn);
00615 fprintf(TFile, "Erase_Var2DualAcc_Map ");
00616 Print_Acc(dacctn);
00617 }
00618 Erase_AccTN(acctn);
00619 Erase_AccTN(dacctn);
00620
00621 typedef std::map<INT32, TN*> Var2Acc;
00622 Var2Acc::iterator it = var2acc.begin();
00623 for(;it != var2acc.end();++it)
00624 {
00625 if (((*it).second == acctn) || ((*it).second == dacctn)) {
00626 var2acc.erase((*it).first);
00627 }
00628 }
00629 return;
00630 }
00631
00632 static void Erase_AddrTN (TN *addrtn) {
00633
00634 if (addrtn == Addr0_TN)
00635 Addreg[0] = 0;
00636 else if (addrtn == Addr1_TN)
00637 Addreg[1] = 0;
00638 else if (addrtn == Addr2_TN)
00639 Addreg[2] = 0;
00640 else if (addrtn == Addr3_TN)
00641 Addreg[3] = 0;
00642 else if (addrtn == Addr4_TN)
00643 Addreg[4] = 0;
00644 else if (addrtn == Addr5_TN)
00645 Addreg[5] = 0;
00646 else if (addrtn == Addr6_TN)
00647 Addreg[6] = 0;
00648 else if (addrtn == Addr7_TN)
00649 Addreg[7] = 0;
00650 else
00651 Is_True(0, ("addrtn is not a valid address register tn"));
00652 return;
00653 }
00654
00655 static void Erase_Var2Addr_Map(INT32 varidx) {
00656 TN *addtn = Get_Addr_from_Varidx(varidx);
00657 Is_True(addtn, ("address register is not used or has been free before"));
00658
00659 if (dotrace) {
00660 fprintf(TFile, "Erase_Var2Addr_Map:: ");
00661 Print_Addr(addtn);
00662 }
00663 Erase_AddrTN(addtn);
00664
00665
00666 typedef std::map<INT32, TN*> Var2Addr;
00667 Var2Addr::iterator it = var2addr.begin();
00668 for(;it != var2addr.end();++it)
00669 {
00670 if ((*it).second == addtn) {
00671 var2addr.erase((*it).first);
00672 }
00673 }
00674 return;
00675 }
00676
00677
00678
00679
00680
00681
00682
00683
00684 TN *Expand_C3_INIT_ACC (WN *intrncall, TN *result, OPS *ops) {
00685
00686 Is_True(WN_kid0(intrncall), ("sl1_l_acquire_acc: 1 argument is null"));
00687 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00688 TN *shl_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
00689 INT32 pregn = Get_Resultidx_Intrncall(intrncall);
00690 TN *acc_tn = Create_Var2Acc_Map(pregn);
00691 Build_OP(TOP_c3_mvtacc, acc_tn, kid0_tn, shl_tn, ops);
00692
00693 return kid0_tn;
00694 }
00695
00696
00697
00698
00699
00700
00701
00702 TN *Expand_C3_SAVE_ACC (WN *intrncall, TN *result, OPS *ops) {
00703
00704 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall), ("sl1_l_free_acc: argument is null"));
00705 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
00706 TN *shr_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
00707 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
00708 TN *acctn = Get_Acc_from_Varidx(varidx);
00709 Is_True(acctn, ("variable hasn't acquired acc register"));
00710
00711 if (!result) {
00712 result = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
00713 }
00714 Build_OP(TOP_c3_mvfacc, result, acctn, shr_tn, ops);
00715
00716 Erase_Var2Acc_Map(varidx);
00717
00718 return result;
00719
00720 }
00721
00722 TN *Expand_C3_MVFS(WN *intrncall, TN *result, OPS *ops) {
00723
00724 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall)),
00725 ("sl1_l_copy_shr_acc: argument is null"));
00726 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00727 TN *shiftnum = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
00728 TN *accid = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
00729 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
00730 TN *acctn = Get_Acc_from_Varidx(varidx);
00731 Is_True(acctn, ("sl1_copy_shr_acc:: argument 1 has not mapped to acc register"));
00732 Is_True(TN_has_value(accid), ("sl1_copy_shr_acc:: arg 3 is not immediate integer"));
00733 if (TN_value(accid) == 1) {
00734 Is_True(Get_DualAccTN(acctn), ("sl1_copy_shr_acc:: arg 1 has not mapped to dual acc register"));
00735 acctn = Get_DualAccTN(acctn);
00736 }
00737 Build_OP(TOP_c3_mvfacc, result, acctn, shiftnum, ops);
00738 return result;
00739 }
00740
00741 TN *Expand_C3_INIT_DACC (WN *intrncall, TN *result, OPS *ops) {
00742
00743 Is_True(WN_kid0(intrncall), ("sl1_l_acquire_dual_acc: argument is incomplete"));
00744 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00745 TN *shl_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
00746 TN *kid1_tn = Expand_Expr (WN_kid2(intrncall), intrncall, NULL);
00747 TN *shl1_tn = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
00748 INT32 varidx = Get_Resultidx_Intrncall(intrncall);
00749 TN *acc_tn = Create_Var2DualAcc_Map(varidx);
00750 TN *dacc_tn = Get_DualAccTN(acc_tn);
00751
00752 Build_OP(TOP_c3_mvtacc, acc_tn, kid0_tn, shl_tn, ops);
00753 Build_OP(TOP_c3_mvtacc, dacc_tn, kid1_tn, shl1_tn, ops);
00754
00755 return kid0_tn;
00756 }
00757
00758 TN *Expand_C3_SAVE_DACC (WN *intrncall, TN *result, OPS *ops) {
00759
00760 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall), ("sl1_l_free_dual_acc: operand is null"));
00761 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
00762
00763 TN *opr_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
00764 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
00765 TN *acc_tn = Get_Acc_from_Varidx(varidx);
00766 Is_True(acc_tn, ("sl1_l_free_dual_acc: variable has not acquired acc register"));
00767 TN *dacc_tn = Get_DualAccTN(acc_tn);
00768 TN *tmp1 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
00769 TN *tmp2 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
00770 TN *tmp0 = Gen_Literal_TN(0,4);
00771
00772 Is_True(TN_has_value(opr_tn), ("sl1_l_free_dual_acc:: the arg 2 must be immediate"));
00773 int oprvalue= TN_value(opr_tn);
00774
00775 if (!result) {
00776 result = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
00777 }
00778 if (oprvalue == 1) {
00779 Build_OP(TOP_c3_mvfacc, tmp1, acc_tn, tmp0, ops);
00780 Build_OP(TOP_c3_mvfacc, tmp2, dacc_tn, tmp0, ops);
00781 Build_OP(TOP_c3_saadds, result, tmp1, tmp2, tmp0, ops);
00782 } else if (oprvalue == 0) {
00783
00784
00785 Build_OP(TOP_c3_mvfacc, result, acc_tn, tmp0, ops);
00786 } else {
00787 Is_True(0, ("sl1_l_free_dual_acc: the 2nd argument is unknown immediate"));
00788 }
00789
00790 Erase_Var2DualAcc_Map(varidx);
00791
00792 return result;
00793
00794 }
00795
00796
00797
00798
00799
00800
00801
00802 TN *Expand_INIT_ADDR (WN *intrncall, TN *result, OPS *ops) {
00803
00804 Is_True(WN_kid0(intrncall), ("sl1_acquire_addr:: argument is incomplete"));
00805 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00806 TN *address_mode = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
00807
00808 INT32 varidx = Get_Resultidx_Intrncall(intrncall);
00809 TN *addr_tn = Create_Var2Add_Map(varidx);
00810 TN *tmp_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
00811
00812 Build_OP(TOP_addiu, tmp_tn, kid0_tn, address_mode, ops);
00813 Build_OP(TOP_c3_mvtaddr, addr_tn, tmp_tn, Gen_Literal_TN(0,4), ops);
00814
00815 return kid0_tn;
00816 }
00817
00818 TN *Expand_SAVE_ADDR (WN *intrncall, TN *result, OPS *ops) {
00819
00820 Is_True(WN_kid0(intrncall), ("sl1_free_addr: argument is incomplete"));
00821 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
00822 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
00823 TN *addrtn = Get_Addr_from_Varidx(varidx);
00824 Is_True(addrtn, ("sl1_free_addr: variable has not arquired address register"));
00825 if (!result) {
00826 result = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
00827 }
00828 Build_OP(TOP_c3_mvfaddr, result, addrtn, Gen_Literal_TN(0,4), ops);
00829
00830 Erase_Var2Addr_Map(varidx);
00831
00832 return result;
00833 }
00834
00835 TN *Expand_C3_PTR (WN *intrncall, TN *result, OPS *ops) {
00836
00837 INT32 pregn1 = Get_ParmVaridx_Intrncall(intrncall, 1);
00838 TN *add1tn = Get_Addr_from_Varidx(pregn1);
00839 if (add1tn) {
00840 Set_Var_AddrTN(AddPregN, add1tn);
00841 if (dotrace) {
00842 fprintf(TFile, "Expand_C3_PTR :: ");
00843 Print_Addr(add1tn);
00844 }
00845 }
00846 else {
00847 TN *rs1 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
00848 Exp_COPY(result, rs1, ops);
00849 }
00850 return result;
00851 }
00852
00853 TN *Expand_SET_ADDRSIZE (WN *intrncall, TN *result, OPS *ops) {
00854
00855 Is_True(WN_kid0(intrncall), ("sl1_set_addrsize: argument is incomplete"));
00856 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
00857 TN *step_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
00858
00859 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
00860 TN *addrtn = Get_Addr_from_Varidx(varidx);
00861 Is_True(addrtn, ("sl1_size_addrsize: argument 0 has not arquired address register"));
00862 Is_True(TN_value(step_tn), ("sl1_size_addrsize: argument 1 should be larger than 0"));
00863
00864 TN *tmp_tn = Gen_Register_TN (ISA_REGISTER_CLASS_integer, 4);
00865 TN *addrs_tn = Get_AddrSize_Reg(addrtn);
00866 Expand_Add(tmp_tn, Zero_TN, step_tn, MTYPE_I4, ops);
00867 Build_OP(TOP_c3_mvtadds, addrs_tn, addrtn, tmp_tn, Gen_Literal_TN(0,4), addrtn, ops);
00868
00869 return result;
00870 }
00871
00872 TN *Expand_Set_CircBuf(WN *intrncall, TN *result, OPS *ops) {
00873 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid(intrncall, 3) && WN_kid(intrncall, 4),
00874 ("sl1_set_CircBuf: arguments are incomplete"));
00875
00876 TN *src_begin = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
00877 TN *src_end = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
00878 TN *circbuf_id = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
00879 TN *cbuf_b = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
00880 TN *cbuf_e = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
00881 TN *value0 = Gen_Literal_TN(0, 4);
00882 Is_True(TN_has_value(circbuf_id) && TN_has_value(cbuf_b) && TN_has_value(cbuf_e), ("sl1_set_circbuf:: 3nd/4th/5th arguments must be immediate"));
00883
00884 TN *begin_addr = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
00885 TN *end_addr = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
00886
00887 Expand_Add(begin_addr, Zero_TN, cbuf_b, MTYPE_I4, ops);
00888 Expand_Add(end_addr, Zero_TN, cbuf_e, MTYPE_I4, ops);
00889
00890 Build_OP(TOP_sw, src_begin, begin_addr, value0, ops);
00891 Set_OP_volatile(OPS_last(ops));
00892 Build_OP(TOP_sw, src_end, end_addr, value0, ops);
00893 Set_OP_volatile(OPS_last(ops));
00894 }
00895
00896
00897 TN* Expand_Float64_Const(WN* intrncall, TN* result, BOOL Is_high, OPS *ops)
00898 {
00899
00900
00901
00902
00903
00904
00905 WN* kid0 = WN_kid0(intrncall);
00906 if(!kid0) {
00907 Print_Src_Line(current_srcpos, stderr);
00908 Fail_FmtAssertion("line %d: Parameter is NULL when handling CVT64", SRCPOS_linenum(current_srcpos));
00909 }
00910
00911 WN* const_val = WN_kid0(kid0);
00912
00913 #ifdef EMULATE_FLOAT_POINT
00914
00915 FmtAssert(WN_rtype(const_val) == MTYPE_F8, ("Expand_Float64_Const: Unexpected Type"));
00916
00917 TN * const_tn = Expand_Expr(const_val, kid0, NULL);
00918
00919 INTRINSIC id = WN_intrinsic(intrncall);
00920 if (id == INTRN_CVT64_LOW)
00921 {
00922 Exp_COPY(result, const_tn, ops);
00923 }
00924 else
00925 {
00926 extern TN* Get_TN_Pair(TN* key);
00927
00928 TN * const_tn_high = Get_TN_Pair(const_tn);
00929 FmtAssert(const_tn_high, ("Expand_Float64_Const: Get const Tn high failed"));
00930
00931 Exp_COPY(result, const_tn_high, ops);
00932 }
00933
00934 #else
00935
00936 if(WN_operator(const_val) != OPR_CONST) {
00937 Print_Src_Line(current_srcpos, stderr);
00938 Fail_FmtAssertion("line %d: constant expected when handling CVT64", SRCPOS_linenum(current_srcpos));
00939 }
00940 ST* sym = WN_st(const_val);
00941 TCON tcon = STC_val(sym);
00942 INTRINSIC id = WN_intrinsic(intrncall);
00943 INT32 val = (id == INTRN_CVT64_LOW) ? TCON_v0(tcon) : TCON_v1(tcon);
00944 if(val == 0)
00945 Exp_COPY(result, Zero_TN, ops);
00946 else {
00947 Build_OP (TOP_lui, result, Gen_Literal_TN((val >> 16)&0xffff, 4), ops);
00948 Build_OP(TOP_ori, result, result, Gen_Literal_TN(val & 0xffff, 4), ops);
00949 }
00950
00951 #endif
00952
00953 return result;
00954
00955 }
00956
00957
00958 TN* Expand_LONGLONG_Const(WN* intrncall, TN* result, BOOL Is_high, OPS *ops)
00959 {
00960
00961
00962
00963
00964
00965
00966 WN* kid0 = WN_kid0(intrncall);
00967 if(!kid0) {
00968 Print_Src_Line(current_srcpos, stderr);
00969 Fail_FmtAssertion("line %d: Parameter is NULL when handling LONLONG CVT64", SRCPOS_linenum(current_srcpos));
00970 }
00971
00972 WN* const_val = WN_kid0(kid0);
00973
00974 #ifdef EMULATE_LONGLONG
00975
00976 FmtAssert((WN_rtype(const_val) == MTYPE_I8) || (WN_rtype(const_val) == MTYPE_U8),
00977 ("Expand_LONGLONG_Const: Unexpected Type"));
00978
00979 TN * const_tn = Expand_Expr(const_val, kid0, NULL);
00980
00981 INTRINSIC id = WN_intrinsic(intrncall);
00982 if (id == INTRN_LONGLONG_CVT64_LOW)
00983 {
00984 Exp_COPY(result, const_tn, ops);
00985 }
00986 else
00987 {
00988 extern TN* Get_TN_Pair(TN* key);
00989
00990 TN * const_tn_high = Get_TN_Pair(const_tn);
00991 FmtAssert(const_tn_high, ("Expand_LONGLONG_Const: Get const Tn high failed"));
00992
00993 Exp_COPY(result, const_tn_high, ops);
00994 }
00995
00996 #else
00997 if(WN_operator(const_val) != OPR_INTCONST) {
00998 Print_Src_Line(current_srcpos, stderr);
00999 Fail_FmtAssertion("line %d: constant expected when handling CVT64", SRCPOS_linenum(current_srcpos));
01000 }
01001
01002 INTRINSIC id = WN_intrinsic(intrncall);
01003 INT32 val = (id == INTRN_LONGLONG_CVT64_LOW) ? (WN_const_val(const_val) & 0xffffffff) :( (WN_const_val(const_val) >> 32) & 0xffffffff);
01004 if(val == 0)
01005 Exp_COPY(result, Zero_TN, ops);
01006 else {
01007 Build_OP (TOP_lui, result, Gen_Literal_TN((val >> 16)&0xffff, 4), ops);
01008 Build_OP(TOP_ori, result, result, Gen_Literal_TN(val & 0xffff, 4), ops);
01009 }
01010 #endif
01011
01012 return result;
01013 }
01014
01015
01016 TN* Expand_Float32_Const(WN* intrncall, TN* result, OPS *ops)
01017 {
01018
01019
01020
01021
01022
01023
01024 WN* kid0 = WN_kid0(intrncall);
01025 if(!kid0) {
01026 Print_Src_Line(current_srcpos, stderr);
01027 Fail_FmtAssertion("line %d: Parameter is NULL when handling CVT64", SRCPOS_linenum(current_srcpos));
01028 }
01029
01030 WN* const_val = WN_kid0(kid0);
01031
01032 #ifdef EMULATE_FLOAT_POINT
01033
01034 FmtAssert(WN_rtype(const_val) == MTYPE_F4, ("Expand_Float32_Const: Unexpected Type"));
01035 TN * const_tn = Expand_Expr(const_val, kid0, NULL);
01036 Exp_COPY(result, const_tn, ops);
01037
01038 #else
01039
01040 if(WN_operator(const_val) != OPR_CONST) {
01041 Print_Src_Line(current_srcpos, stderr);
01042 Fail_FmtAssertion("line %d: constant expected when handling CVT32", SRCPOS_linenum(current_srcpos));
01043 }
01044
01045 ST* sym = WN_st(const_val);
01046 TCON tcon = STC_val(sym);
01047 INTRINSIC id = WN_intrinsic(intrncall);
01048 INT32 val = TCON_v0(tcon);
01049 if(val == 0)
01050 Exp_COPY(result, Zero_TN, ops);
01051 else {
01052 Build_OP (TOP_lui, result, Gen_Literal_TN((val >> 16)&0xffff, 4), ops);
01053 Build_OP(TOP_ori, result, result, Gen_Literal_TN(val & 0xffff, 4), ops);
01054 }
01055 #endif
01056
01057 return result;
01058 }
01059
01060 TN *Expand_C3_aadda(WN *intrncall, TN *result, OPS *ops) {
01061 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall)),
01062 ("Sl1_aadda:arguments are incomplete"));
01063
01064 TN *accd = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01065 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01066 TN *accs = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01067 TN *m = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01068 TN *paired = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01069 UINT flag= 0;
01070 TN *tmp0 = Gen_Literal_TN(0, 4);
01071 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
01072 TN *accd_tn = Get_Acc_from_Varidx(v1);
01073 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 2);
01074 TN *accs_tn = Get_Acc_from_Varidx(v2);
01075
01076 Is_True(TN_has_value(paired), ("last parameter should be 0 or 1"));
01077 if (TN_value(paired) == 1){
01078 accs_tn = Get_DualAccTN(accd_tn);
01079 Is_True(accs_tn, ("first acc should acquire dual acc"));
01080 } else {
01081 v2 = Get_ParmVaridx_Intrncall(intrncall, 2);
01082 accs_tn = Get_Acc_from_Varidx(v2);
01083 }
01084
01085 if (!accd_tn) {
01086 accd_tn = Get_New_AccTN();
01087 Build_OP(TOP_c3_mvtacc, accd_tn, accd, tmp0, ops);
01088 flag = 1;
01089 } else {
01090 Set_Var_AccTN(AccPregN, accd_tn);
01091 }
01092 if (!accs_tn) {
01093 accs_tn = Get_New_AccTN();
01094 Build_OP(TOP_c3_mvtacc, accs_tn, accs, tmp0, ops);
01095 flag |=2;
01096 }
01097 Build_OP(TOP_c3_aadda, accd_tn, acm, accs_tn, m, accd_tn, ops);
01098
01099 if (flag & 1) {
01100 Build_OP(TOP_c3_mvfacc, result, accd_tn, tmp0, ops);
01101 Erase_AccTN(accd_tn);
01102 }
01103 if (flag & 2) {
01104 Erase_AccTN(accs_tn);
01105 }
01106 return result;
01107 }
01108
01109 TN *Expand_C3_bitr(WN *intrncall, TN *result, OPS *ops) {
01110 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall)),
01111 ("Sl1_C3_bitr: operand is null"));
01112
01113 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01114 TN *uimm5_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01115 TN *mode_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01116
01117 Build_OP(TOP_c3_bitr, result, kid0_tn, uimm5_tn, mode_tn, ops);
01118 return result;
01119 }
01120
01121 TN *Expand_C3_cs(WN *intrncall, TN *result, OPS *ops) {
01122 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall)),
01123 ("Sl1_C3_CS: operand is null"));
01124
01125 TN *rs0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01126 TN *rs1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01127 TN *mode_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01128
01129 Build_OP(TOP_c3_cs, result, HI_TN, rs0_tn, rs1_tn, mode_tn, HI_TN, ops);
01130 return result;
01131 }
01132
01133 TN *Expand_C3_Mode0(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
01134 Is_True((const_parm_nums < 3 ), ("const nums < 3"));
01135
01136 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01137 TN *kid1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01138 TN *uimm5[3];
01139 TN *oper;
01140 INT32 value = -1;
01141 INT i=0;
01142 if (has_oper) {
01143 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, (2+const_parm_nums))), 4);
01144 if (TN_has_value(oper)) {
01145 value = TN_value(oper);
01146 } else {
01147 Is_True(0, ("should be 0 or 1"));
01148 }
01149 }
01150 while (const_parm_nums > 0) {
01151 uimm5[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 2+i)), 4);
01152 const_parm_nums--;
01153 i++;
01154 }
01155 switch (top) {
01156 case TOP_c3_dadd: top = value ==1 ? TOP_c3_dsub : top; break;
01157 case TOP_c3_saadds: top = value == 1 ? TOP_c3_sasubs: top; break;
01158 case TOP_c3_saaddsh: top = value == 1 ? TOP_c3_sasubsh: top; break;
01159 case TOP_c3_samulsh: break;
01160 default: Is_True(0, ("unknown TOP"));
01161 }
01162
01163 switch (i) {
01164 case 0: Build_OP(top, result, kid0_tn, kid1_tn, ops); break;
01165 case 1: Build_OP(top, result, kid0_tn, kid1_tn, uimm5[0], ops); break;
01166 default: Is_True(0, ("now only use 0 or 1 uimm5"));
01167 }
01168 return result;
01169 }
01170
01171
01172
01173 TN *Expand_C3_Mode1(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops) {
01174 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01175 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01176 TN *rs1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01177 TN *rs2 = Expand_Expr(WN_kid3(intrncall), intrncall, NULL);
01178 TN *const_parm[3];
01179 UINT32 flag = 0;
01180 TN *tmp0 = Gen_Literal_TN(0, 4);
01181 INT32 i = 0;
01182 while(const_parm_nums > 0) {
01183 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+i)), 4);
01184 const_parm_nums--;
01185 i++;
01186 }
01187 Is_True(WN_kid(intrncall, 4+const_parm_nums), ("no oper kid"));
01188 TN *oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+i)), 4);
01189 INT32 value = -1;
01190 if (TN_has_value(oper)) {
01191 value = TN_value(oper);
01192 } else {
01193 Is_True(0, ("should be 0 or 1"));
01194 }
01195
01196 switch (top) {
01197 case TOP_c3_mac: top = value == 1 ? TOP_c3_macn : top; break;
01198 case TOP_c3_mula: top = value == 1 ? TOP_c3_mulan : top; break;
01199 default: Is_True(0, ("unknown TOP"));
01200 }
01201
01202 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
01203 TN *acc_tn = Get_Acc_from_Varidx(v1);
01204
01205 if (!acc_tn) {
01206 acc_tn = Get_New_AccTN();
01207 if (top == TOP_c3_mac || top == TOP_c3_macn)
01208 Build_OP(TOP_c3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
01209 flag = 1;
01210 } else {
01211 Set_Var_AccTN(AccPregN, acc_tn);
01212 }
01213 if ((top == TOP_c3_mula) || (top == TOP_c3_mulan)) {
01214 switch (i) {
01215 case 0: Build_OP(top, acc_tn, acm, rs1, rs2, ops); break;
01216 case 1: Build_OP(top, acc_tn, acm, rs1, rs2, const_parm[0], ops); break;
01217 case 2: Build_OP(top, acc_tn, acm, rs1, rs2, const_parm[0], const_parm[1], ops); break;
01218 case 3: Build_OP(top, acc_tn, acm, rs1, rs2, const_parm[0], const_parm[1], const_parm[2], ops); break;
01219 default: Is_True(0, ("const num should <=3 "));
01220 }
01221 } else {
01222 switch (i) {
01223 case 0: Build_OP(top, acc_tn, acm, rs1, rs2, acc_tn, ops); break;
01224 case 1: Build_OP(top, acc_tn, acm, rs1, rs2, const_parm[0], acc_tn, ops); break;
01225 case 2: Build_OP(top, acc_tn, acm, rs1, rs2, const_parm[0], const_parm[1], acc_tn, ops); break;
01226 case 3: Build_OP(top, acc_tn, acm, rs1, rs2, const_parm[0], const_parm[1], const_parm[2], acc_tn, ops); break;
01227 default: Is_True(0, ("const num should <=3 "));
01228 }
01229 }
01230 if (flag == 1) {
01231 Build_OP(TOP_c3_mvfacc, result, acc_tn, tmp0, ops);
01232 Erase_AccTN(acc_tn);
01233 }
01234
01235 return result;
01236 }
01237
01238
01239 TN *Expand_C3_Mode2(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops) {
01240 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01241 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01242 TN *rs1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01243 TN *rs2 = Expand_Expr(WN_kid3(intrncall), intrncall, NULL);
01244 TN *const_parm[3];
01245 UINT32 flag = 0;
01246 TN *tmp0 = Gen_Literal_TN(0, 4);
01247 INT32 i = 0;
01248 while(const_parm_nums > 0) {
01249 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+i)), 4);
01250 const_parm_nums--;
01251 i++;
01252 }
01253 Is_True(WN_kid(intrncall, 4+const_parm_nums), ("no oper kid"));
01254 TN *oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+i)), 4);
01255 INT32 value = -1;
01256 if (TN_has_value(oper)) {
01257 value = TN_value(oper);
01258 } else {
01259 Is_True(0, ("should be 0 or 1"));
01260 }
01261
01262 switch (top) {
01263 case TOP_c3_dmac: top = value == 1 ? TOP_c3_dmacn : top; break;
01264 case TOP_c3_dmula: top = value == 1 ? TOP_c3_dmulan : top; break;
01265 default: Is_True(0, ("unkown TOP"));
01266 }
01267
01268 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
01269 TN *acc_tn = Get_Acc_from_Varidx(v1);
01270 TN *acc1_tn;
01271 if (!acc_tn) {
01272 acc_tn = Get_New_DualAccTN();
01273 acc1_tn = Get_DualAccTN(acc_tn);
01274 if (top == TOP_c3_dmac || top == TOP_c3_dmacn) {
01275 Build_OP(TOP_c3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
01276 Build_OP(TOP_c3_mvtacc, acc1_tn, Zero_TN, tmp0, ops);
01277 }
01278 flag = 1;
01279 } else {
01280 Set_Var_AccTN(AccPregN, acc_tn);
01281 acc1_tn = Get_DualAccTN(acc_tn);
01282 }
01283 switch (i) {
01284 case 0: Build_OP(top, acc_tn, acc1_tn, acm, rs1, rs2, acc_tn, acc1_tn, ops); break;
01285 case 1: Build_OP(top, acc_tn, acc1_tn, acm, rs1, rs2, const_parm[0], acc_tn, acc1_tn, ops); break;
01286 case 2: Build_OP(top, acc_tn, acc1_tn, acm, rs1, rs2, const_parm[0], const_parm[1], acc_tn, acc1_tn, ops); break;
01287 case 3: Build_OP(top, acc_tn, acc1_tn, acm, rs1, rs2, const_parm[0], const_parm[1], const_parm[2], acc_tn, acc1_tn, ops); break;
01288 default: Is_True(0, ("const num should <=3 "));
01289 }
01290
01291 if (flag == 1) {
01292 TN *tmp1 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01293 TN *tmp2 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01294 Build_OP(TOP_c3_mvfacc, tmp1, acc_tn, tmp0, ops);
01295 Build_OP(TOP_c3_mvfacc, tmp2, acc1_tn, tmp0, ops);
01296 Build_OP(TOP_c3_saadds, result, tmp1, tmp2, tmp0, ops);
01297 Erase_AccTN(acc_tn);
01298 Erase_AccTN(acc1_tn);
01299 }
01300
01301 }
01302
01303
01304 TN *Expand_C3_Mode3(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
01305 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01306 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01307 TN *as1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01308 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01309 TN *as2 = Expand_Expr(WN_kid(intrncall, 4), intrncall, NULL);
01310 TN *am2 = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);
01311
01312 TN *const_parm[3];
01313 UINT32 flag = 0;
01314 TN *tmp0 = Gen_Literal_TN(0, 4);
01315 INT32 i = 0;
01316 TN *oper;
01317 INT32 value = -1;
01318
01319 if (has_oper) {
01320 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6+const_parm_nums)), 4);
01321 if (TN_has_value(oper)) {
01322 value = TN_value(oper);
01323 } else {
01324 Is_True(0, ("should be 0 or 1"));
01325 }
01326 }
01327 while(const_parm_nums > 0) {
01328 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6+i)), 4);
01329 const_parm_nums--;
01330 i++;
01331 }
01332
01333 switch (top) {
01334 case TOP_c3_mac_a: top = value == 1 ? TOP_c3_macn_a : top; break;
01335 case TOP_c3_mula_a: break;
01336 default: Is_True(0, ("unknown TOP"));
01337 }
01338
01339 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
01340 TN *acc_tn = Get_Acc_from_Varidx(v1);
01341 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 2);
01342 TN *add1_tn = Get_Addr_from_Varidx(v2);
01343 INT32 v3 = Get_ParmVaridx_Intrncall(intrncall, 4);
01344 TN *add2_tn = Get_Addr_from_Varidx(v3);
01345
01346 if (!acc_tn) {
01347 acc_tn = Get_New_AccTN();
01348 if (top != TOP_c3_mula_a)
01349 Build_OP(TOP_c3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
01350 flag = 1;
01351 } else {
01352 Set_Var_AccTN(AccPregN, acc_tn);
01353 }
01354 if (!add1_tn) {
01355 add1_tn = Get_New_AddrTN();
01356 Build_OP(TOP_c3_mvtaddr, add1_tn, as1, tmp0, ops);
01357 flag |= 2;
01358 }
01359 if (!add2_tn) {
01360 add2_tn = Get_New_AddrTN();
01361 Build_OP(TOP_c3_mvtaddr, add2_tn, as2, tmp0, ops);
01362 flag |= 4;
01363 }
01364
01365 if (top == TOP_c3_mula_a) {
01366 switch (i) {
01367 case 0: Build_OP(top, acc_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, ops); break;
01368 case 1: Build_OP(top, acc_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, const_parm[0], ops); break;
01369 default: Is_True(0, ("const num should <=1 "));
01370 }
01371 } else {
01372 switch (i) {
01373 case 0: Build_OP(top, acc_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, acc_tn, ops); break;
01374 case 1: Build_OP(top, acc_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, const_parm[0], acc_tn, ops); break;
01375 default: Is_True(0, ("const num should <=1 "));
01376 }
01377 }
01378
01379 Set_OP_To_WN_Map(intrncall);
01380
01381 if (flag & 1) {
01382 Build_OP(TOP_c3_mvfacc, result, acc_tn, tmp0, ops);
01383 Erase_AccTN(acc_tn);
01384 }
01385 if (flag & 2) {
01386 Build_OP(TOP_c3_mvfaddr, as1, add1_tn, tmp0, ops);
01387 Erase_AddrTN(add1_tn);
01388 }
01389 if (flag & 4) {
01390 Build_OP(TOP_c3_mvfaddr, as2, add2_tn, tmp0, ops);
01391 Erase_AddrTN(add2_tn);
01392 }
01393 return result;
01394
01395 }
01396
01397
01398 TN *Expand_C3_Mode4(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
01399 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01400 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01401 TN *rs1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01402 TN *as1 = Expand_Expr(WN_kid(intrncall, 3), intrncall, NULL);
01403 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01404
01405 TN *const_parm[3];
01406 UINT32 flag = 0;
01407 TN *tmp0 = Gen_Literal_TN(0, 4);
01408 INT32 i = 0;
01409 TN *oper;
01410 INT32 value = -1;
01411
01412 if (has_oper) {
01413 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5 + const_parm_nums)), 4);
01414 if (TN_has_value(oper)) {
01415 value = TN_value(oper);
01416 } else {
01417 Is_True(0, ("should be 0 or 1"));
01418 }
01419 }
01420 while(const_parm_nums > 0) {
01421 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5+i)), 4);
01422 const_parm_nums--;
01423 i++;
01424 }
01425
01426 switch (top) {
01427 case TOP_c3_mac_ar: top = value == 1 ? TOP_c3_macn_ar : top; break;
01428 case TOP_c3_mula_ar: break;
01429 default: Is_True(0, ("unknown TOP"));
01430 }
01431
01432 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
01433 TN *acc_tn = Get_Acc_from_Varidx(v1);
01434 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 3);
01435 TN *add1_tn = Get_Addr_from_Varidx(v2);
01436
01437 if (!acc_tn) {
01438 acc_tn = Get_New_AccTN();
01439 if (top != TOP_c3_mula_ar)
01440 Build_OP(TOP_c3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
01441 flag = 1;
01442 } else {
01443 Set_Var_AccTN(AccPregN, acc_tn);
01444 }
01445 if (!add1_tn) {
01446 add1_tn = Get_New_AddrTN();
01447 Build_OP(TOP_c3_mvtaddr, add1_tn, as1, tmp0, ops);
01448 flag |= 2;
01449 }
01450
01451 switch (i) {
01452 case 0:
01453 {
01454 if (top == TOP_c3_mula_ar)
01455 Build_OP(top, acc_tn, add1_tn, acm, rs1, add1_tn, am1, ops);
01456 else
01457 Build_OP(top, acc_tn, add1_tn, acm, rs1, add1_tn, am1, acc_tn, ops);
01458 break;
01459 }
01460 case 1:
01461 {
01462 if (top == TOP_c3_mula_ar)
01463 Build_OP(top, acc_tn, add1_tn, acm, rs1, add1_tn, am1, const_parm[0], ops);
01464 else
01465 Build_OP(top, acc_tn, add1_tn, acm, rs1, add1_tn, am1, const_parm[0], acc_tn, ops);
01466 break;
01467 }
01468 default: Is_True(0, ("const num should <=1 "));
01469 }
01470
01471 Set_OP_To_WN_Map(intrncall);
01472
01473 if (flag & 1) {
01474 Build_OP(TOP_c3_mvfacc, result, acc_tn, tmp0, ops);
01475 Erase_AccTN(acc_tn);
01476 }
01477 if (flag & 2) {
01478 Build_OP(TOP_c3_mvfaddr, as1, add1_tn, tmp0, ops);
01479 Erase_AddrTN(add1_tn);
01480 }
01481 return result;
01482
01483 }
01484
01485
01486 TN *Expand_C3_Mode5(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
01487 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01488 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01489 TN *rs1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01490
01491 TN *const_parm[4];
01492 UINT32 flag = 0;
01493 TN *tmp0 = Gen_Literal_TN(0, 4);
01494 INT32 i = 0;
01495 TN *oper;
01496 INT32 value = -1;
01497
01498 if (has_oper) {
01499 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 3+const_parm_nums)), 4);
01500 if (TN_has_value(oper)) {
01501 value = TN_value(oper);
01502 } else {
01503 Is_True(0, ("should be 0 or 1"));
01504 }
01505 }
01506 while(const_parm_nums > 0) {
01507 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 3+i)), 4);
01508 const_parm_nums--;
01509 i++;
01510 }
01511
01512 switch (top) {
01513 case TOP_c3_mac_i: top = value == 1 ? TOP_c3_macn_i : top; break;
01514 case TOP_c3_shlata_i: top = value == 1 ? TOP_c3_shrata_i : top; break;
01515 case TOP_c3_mula_i: break;
01516 case TOP_c3_sadda: break;
01517 case TOP_c3_shav: break;
01518
01519 default: Is_True(0, ("unknown TOP"));
01520 }
01521
01522 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
01523 TN *acc_tn = Get_Acc_from_Varidx(v1);
01524
01525 if (!acc_tn) {
01526 acc_tn = Get_New_AccTN();
01527 if (top != TOP_c3_mula_i)
01528 Build_OP(TOP_c3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
01529 flag = 1;
01530 } else {
01531 Set_Var_AccTN(AccPregN, acc_tn);
01532 }
01533
01534 if ((top == TOP_c3_mula_i) || (top == TOP_c3_shlata_i) || (top == TOP_c3_shrata_i)) {
01535
01536 switch (i) {
01537 case 0: Build_OP(top, acc_tn, acm, rs1, ops); break;
01538 case 1: Build_OP(top, acc_tn, acm, rs1, const_parm[0], ops); break;
01539 case 2: Build_OP(top, acc_tn, acm, rs1, const_parm[0], const_parm[1], ops); break;
01540 case 3: Build_OP(top, acc_tn, acm, rs1, const_parm[0], const_parm[1], const_parm[2], ops); break;
01541 case 4: Build_OP(top, acc_tn, acm, rs1, const_parm[0], const_parm[1], const_parm[2], const_parm[3], ops); break;
01542 default: Is_True(0, ("const num should <=4 "));
01543 }
01544 } else {
01545
01546 switch (i) {
01547 case 0: Build_OP(top, acc_tn, acm, rs1, acc_tn, ops); break;
01548 case 1: Build_OP(top, acc_tn, acm, rs1, const_parm[0], acc_tn, ops); break;
01549 case 2: Build_OP(top, acc_tn, acm, rs1, const_parm[0], const_parm[1], acc_tn, ops); break;
01550 case 3: Build_OP(top, acc_tn, acm, rs1, const_parm[0], const_parm[1], const_parm[2], acc_tn, ops); break;
01551 case 4: Build_OP(top, acc_tn, acm, rs1, const_parm[0], const_parm[1], const_parm[2], const_parm[3], acc_tn, ops); break;
01552 default: Is_True(0, ("const num should <=4 "));
01553 }
01554 }
01555
01556 if (flag & 1) {
01557 Build_OP(TOP_c3_mvfacc, result, acc_tn, tmp0, ops);
01558 Erase_AccTN(acc_tn);
01559 }
01560
01561 return result;
01562 }
01563
01564
01565 TN *Expand_C3_Mode6(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
01566
01567 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01568 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01569 TN *const_parm[3];
01570 UINT32 flag = 0;
01571 TN *tmp0 = Gen_Literal_TN(0, 4);
01572 INT32 i = 0;
01573 TN *oper;
01574 INT32 value = -1;
01575
01576 if (has_oper) {
01577 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 2+const_parm_nums)), 4);
01578 if (TN_has_value(oper)) {
01579 value = TN_value(oper);
01580 } else {
01581 Is_True(0, ("should be 0 or 1"));
01582 }
01583 }
01584
01585 switch (top) {
01586 case TOP_c3_round: break;
01587 case TOP_c3_shla_i: top = value == 1 ? TOP_c3_shra_i : top ; break;
01588 default: Is_True(0, ("unknown TOP"));
01589 }
01590
01591 while(const_parm_nums > 0) {
01592 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 2+i)), 4);
01593 const_parm_nums--;
01594 i++;
01595 }
01596
01597 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
01598 TN *acc_tn = Get_Acc_from_Varidx(v1);
01599
01600 if (!acc_tn) {
01601 acc_tn = Get_New_AccTN();
01602 Build_OP(TOP_c3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
01603 flag = 1;
01604 } else {
01605 Set_Var_AccTN(AccPregN, acc_tn);
01606 }
01607
01608 switch (i) {
01609 case 0: Build_OP(top, acc_tn, acm, acc_tn, ops); break;
01610 case 1: Build_OP(top, acc_tn, acm, const_parm[0], acc_tn, ops); break;
01611 case 2: Build_OP(top, acc_tn, acm, const_parm[0], const_parm[1], acc_tn, ops); break;
01612 case 3: Build_OP(top, acc_tn, acm, const_parm[0], const_parm[1], const_parm[2], acc_tn, ops); break;
01613 default: Is_True(0, ("const num should <=3 "));
01614 }
01615
01616 if (flag & 1) {
01617 Build_OP(TOP_c3_mvfacc, result, acc_tn, tmp0, ops);
01618 Erase_AccTN(acc_tn);
01619 }
01620
01621 }
01622
01623
01624
01625 TN *Expand_C3_Mode7(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
01626
01627 TN *as1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01628 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01629 TN *as2 = Expand_Expr(WN_kid(intrncall, 2), intrncall, NULL);
01630 TN *am2 = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 3)), 4);
01631
01632 TN *const_parm[3];
01633 UINT32 flag = 0;
01634 TN *tmp0 = Gen_Literal_TN(0, 4);
01635 INT32 i = 0;
01636 TN *oper;
01637 INT32 value = -1;
01638
01639 if (has_oper) {
01640 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+const_parm_nums)), 4);
01641 if (TN_has_value(oper)) {
01642 value = TN_value(oper);
01643 } else {
01644 Is_True(0, ("should be 0 or 1"));
01645 }
01646 }
01647 while(const_parm_nums > 0) {
01648 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+i)), 4);
01649 const_parm_nums--;
01650 i++;
01651 }
01652
01653 switch (top) {
01654 case TOP_c3_saadd_a: top = value == 1 ? TOP_c3_sasub_a : top; break;
01655 case TOP_c3_saaddh_a: top = value == 1 ? TOP_c3_sasubh_a : top; break;
01656 case TOP_c3_samulh_a: break;
01657 default: Is_True(0, ("unknown TOP"));
01658 }
01659
01660 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 0);
01661 TN *add1_tn = Get_Addr_from_Varidx(v2);
01662 INT32 v3 = Get_ParmVaridx_Intrncall(intrncall, 2);
01663 TN *add2_tn = Get_Addr_from_Varidx(v3);
01664
01665 if (!add1_tn) {
01666 add1_tn = Get_New_AddrTN();
01667 Build_OP(TOP_c3_mvtaddr, add1_tn, as1, tmp0, ops);
01668 flag |= 1;
01669 }
01670 if (!add2_tn) {
01671 add2_tn = Get_New_AddrTN();
01672 Build_OP(TOP_c3_mvtaddr, add2_tn, as2, tmp0, ops);
01673 flag |= 2;
01674 }
01675
01676 switch (i) {
01677 case 0: Build_OP(top, result, add1_tn, add2_tn, add1_tn, am1, add2_tn, am2, ops); break;
01678 case 1: Build_OP(top, result, add1_tn, add2_tn, add1_tn, am1, add2_tn, am2, const_parm[0], ops); break;
01679 case 2: Build_OP(top, result, add1_tn, add2_tn, add1_tn, am1, add2_tn, am2, const_parm[0], const_parm[1], ops); break;
01680 default: Is_True(0, ("const num should <= 2 "));
01681 }
01682
01683 Set_OP_To_WN_Map(intrncall);
01684
01685 if (flag & 1) {
01686 Build_OP(TOP_c3_mvfaddr, as1, add1_tn, tmp0, ops);
01687 Erase_AddrTN(add1_tn);
01688 }
01689 if (flag & 2) {
01690 Build_OP(TOP_c3_mvfaddr, as2, add2_tn, tmp0, ops);
01691 Erase_AddrTN(add2_tn);
01692 }
01693 return result;
01694
01695 }
01696
01697
01698 TN *Expand_C3_Mode8(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
01699 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01700 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01701 TN *as1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01702 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01703 TN *as2 = Expand_Expr(WN_kid(intrncall, 4), intrncall, NULL);
01704 TN *am2 = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);
01705
01706 TN *const_parm[3];
01707 UINT32 flag = 0;
01708 TN *tmp0 = Gen_Literal_TN(0, 4);
01709 INT32 i = 0;
01710 TN *oper;
01711 INT32 value = -1;
01712
01713 if (has_oper) {
01714 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6+const_parm_nums)), 4);
01715 if (TN_has_value(oper)) {
01716 value = TN_value(oper);
01717 } else {
01718 Is_True(0, ("should be 0 or 1"));
01719 }
01720 }
01721 while(const_parm_nums > 0) {
01722 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6+i)), 4);
01723 const_parm_nums--;
01724 i++;
01725 }
01726
01727 switch (top) {
01728 case TOP_c3_dmac_a: top = value == 1 ? TOP_c3_dmacn_a : top; break;
01729 case TOP_c3_dmula_a: top = value == 1 ? TOP_c3_dmulan_a : top; break;
01730 default: Is_True(0, ("unknown TOP"));
01731 }
01732
01733 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
01734 TN *acc_tn = Get_Acc_from_Varidx(v1);
01735 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 2);
01736 TN *add1_tn = Get_Addr_from_Varidx(v2);
01737 INT32 v3 = Get_ParmVaridx_Intrncall(intrncall, 4);
01738 TN *add2_tn = Get_Addr_from_Varidx(v3);
01739 TN *acc1_tn;
01740
01741 if (!acc_tn) {
01742 acc_tn = Get_New_DualAccTN();
01743 acc1_tn = Get_DualAccTN(acc_tn);
01744 if (top == TOP_c3_dmac_a || top == TOP_c3_dmacn_a) {
01745 Build_OP(TOP_c3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
01746 Build_OP(TOP_c3_mvtacc, acc1_tn, Zero_TN, tmp0, ops);
01747 }
01748 flag = 1;
01749 } else {
01750 Set_Var_AccTN(AccPregN, acc_tn);
01751 acc1_tn = Get_DualAccTN(acc_tn);
01752 }
01753 if (!add1_tn) {
01754 add1_tn = Get_New_AddrTN();
01755 Build_OP(TOP_c3_mvtaddr, add1_tn, as1, tmp0, ops);
01756 flag |= 2;
01757 }
01758 if (!add2_tn) {
01759 add2_tn = Get_New_AddrTN();
01760 Build_OP(TOP_c3_mvtaddr, add2_tn, as2, tmp0, ops);
01761 flag |= 4;
01762 }
01763
01764 if (top == TOP_c3_dmula_a || top == TOP_c3_dmulan_a) {
01765 switch (i) {
01766 case 0: Build_OP(top, acc_tn, acc1_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, ops); break;
01767 case 1: Build_OP(top, acc_tn, acc1_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, const_parm[0], ops); break;
01768 case 2: Build_OP(top, acc_tn, acc1_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, const_parm[0], const_parm[1], ops); break;
01769 default: Is_True(0, ("const num should <=2 "));
01770 }
01771 } else {
01772 switch (i) {
01773 case 0: Build_OP(top, acc_tn, acc1_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, acc_tn, acc1_tn, ops); break;
01774 case 1: Build_OP(top, acc_tn, acc1_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, const_parm[0], acc_tn, acc1_tn, ops); break;
01775 case 2: Build_OP(top, acc_tn, acc1_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, const_parm[0], const_parm[1], acc_tn, acc1_tn, ops); break;
01776 default: Is_True(0, ("const num should <=2 "));
01777 }
01778 }
01779
01780 Set_OP_To_WN_Map(intrncall);
01781
01782 if (flag & 1) {
01783 TN *tmp1 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01784 TN *tmp2 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01785 Build_OP(TOP_c3_mvfacc, tmp1, acc_tn, tmp0, ops);
01786 Build_OP(TOP_c3_mvfacc, tmp2, acc1_tn, tmp0, ops);
01787 Build_OP(TOP_c3_saadds, result, tmp1, tmp2, tmp0, ops);
01788 Erase_AccTN(acc_tn);
01789 Erase_AccTN(acc1_tn);
01790 }
01791 if (flag & 2) {
01792 Build_OP(TOP_c3_mvfaddr, as1, add1_tn, tmp0, ops);
01793 Erase_AddrTN(add1_tn);
01794 }
01795 if (flag & 4) {
01796 Build_OP(TOP_c3_mvfaddr, as2, add2_tn, tmp0, ops);
01797 Erase_AddrTN(add2_tn);
01798 }
01799 return result;
01800
01801 }
01802
01803
01804 TN *Expand_C3_Mode9(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
01805 TN *rs1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01806 TN *const_parm[3];
01807 UINT32 flag = 0;
01808 TN *tmp0 = Gen_Literal_TN(0, 4);
01809 INT32 i = 0;
01810 TN *oper;
01811 INT32 value = -1;
01812
01813 if (has_oper) {
01814 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 1+const_parm_nums)), 4);
01815 if (TN_has_value(oper)) {
01816 value = TN_value(oper);
01817 } else {
01818 Is_True(0, ("should be 0 or 1"));
01819 }
01820 }
01821 while(const_parm_nums > 0) {
01822 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 1+i)), 4);
01823 const_parm_nums--;
01824 i++;
01825 }
01826
01827 switch (top) {
01828 case TOP_c3_dshll_i: top = value == 1 ? TOP_c3_dshrl_i : top; break;
01829 case TOP_c3_revb: break;
01830 default: Is_True(0, ("unknown TOP"));
01831 }
01832
01833 switch (i) {
01834 case 0: Build_OP(top, result, rs1, ops);
01835 case 1: Build_OP(top, result, rs1, const_parm[0], ops); break;
01836 case 2: Build_OP(top, result, rs1, const_parm[0], const_parm[1], ops); break;
01837 default: Is_True(0, ("const parm number < 3"));
01838 }
01839
01840 return result;
01841 }
01842
01843
01844 TN *Expand_C3_Mode10(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
01845 TN *as1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01846 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01847 TN *dtyp = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01848
01849 TN *const_parm[3];
01850 UINT32 flag = 0;
01851 TN *tmp0 = Gen_Literal_TN(0, 4);
01852 INT32 i = 0;
01853 TN *oper;
01854 INT32 value = -1;
01855
01856 if (has_oper) {
01857 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 3+const_parm_nums)), 4);
01858 if (TN_has_value(oper)) {
01859 value = TN_value(oper);
01860 } else {
01861 Is_True(0, ("should be 0 or 1"));
01862 }
01863 }
01864 while(const_parm_nums > 0) {
01865 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 3+i)), 4);
01866 const_parm_nums--;
01867 i++;
01868 }
01869
01870 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 0);
01871 TN *add1_tn = Get_Addr_from_Varidx(v2);
01872
01873 if (!add1_tn) {
01874 add1_tn = Get_New_AddrTN();
01875 Build_OP(TOP_c3_mvtaddr, add1_tn, as1, tmp0, ops);
01876 flag |= 1;
01877 }
01878
01879 switch (top) {
01880 case TOP_c3_ld: top = value == 1 ? TOP_c3_fftld : top; break;
01881 default: Is_True(0, ("unknown TOP"));
01882 }
01883
01884 switch (i) {
01885 case 0: Build_OP(top, result, add1_tn, add1_tn, tmp0, am1, dtyp, ops); break;
01886 case 1: Build_OP(top, result, add1_tn, add1_tn, tmp0, am1, dtyp, const_parm[0], ops); break;
01887 default: Is_True(0, ("const num should <=1 "));
01888 }
01889
01890 Set_OP_To_WN_Map(intrncall);
01891
01892 if (flag & 1) {
01893 Build_OP(TOP_c3_mvfaddr, as1, add1_tn, tmp0, ops);
01894 Erase_AddrTN(add1_tn);
01895 }
01896
01897 return result;
01898 }
01899
01900
01901 TN *Expand_C3_Mode11(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
01902 TN *rs1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01903 TN *as1 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01904 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01905 TN *dtyp = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01906
01907 TN *const_parm[3];
01908 UINT32 flag = 0;
01909 TN *tmp0 = Gen_Literal_TN(0, 4);
01910 INT32 i = 0;
01911 TN *oper;
01912 INT32 value = -1;
01913
01914 if (has_oper) {
01915 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+const_parm_nums)), 4);
01916 if (TN_has_value(oper)) {
01917 value = TN_value(oper);
01918 } else {
01919 Is_True(0, ("should be 0 or 1"));
01920 }
01921 }
01922 while(const_parm_nums > 0) {
01923 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+i)), 4);
01924 const_parm_nums--;
01925 i++;
01926 }
01927
01928 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 1);
01929 TN *add1_tn = Get_Addr_from_Varidx(v2);
01930
01931 if (!add1_tn) {
01932 add1_tn = Get_New_AddrTN();
01933 Build_OP(TOP_c3_mvtaddr, add1_tn, as1, tmp0, ops);
01934 flag |= 1;
01935 }
01936
01937 switch (top) {
01938 case TOP_c3_st: top = value == 1 ? TOP_c3_fftst : top; break;
01939 default: Is_True(0, ("unknown TOP"));
01940 }
01941
01942 switch (i) {
01943 case 0: Build_OP(top, add1_tn, rs1, add1_tn, tmp0, am1, dtyp, ops); break;
01944 case 1: Build_OP(top, add1_tn, rs1, add1_tn, tmp0, am1, dtyp, const_parm[0], ops); break;
01945 default: Is_True(0, ("const num should <=1 "));
01946 }
01947
01948 Set_OP_To_WN_Map(intrncall);
01949
01950 if (flag & 1) {
01951 Build_OP(TOP_c3_mvfaddr, as1, add1_tn, tmp0, ops);
01952 Erase_AddrTN(add1_tn);
01953 }
01954
01955 return result;
01956 }
01957
01958
01959 TN *Expand_C3_shlafa_i(WN *intrncall, TN *result, OPS *ops) {
01960 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01961 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01962 TN *uimm5 = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01963 TN *oper = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01964 INT32 value = -1;
01965 UINT32 flag = 0;
01966 TN *tmp0 = Gen_Literal_TN(0, 4);
01967 if (TN_has_value(oper)) {
01968 value = TN_value(oper);
01969 } else {
01970 Is_True(0, ("should have oper"));
01971 }
01972 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
01973 TN *acc_tn = Get_Acc_from_Varidx(v1);
01974
01975 TOP top = value == 1 ? TOP_c3_shrafa_i : TOP_c3_shlafa_i;
01976
01977 if (!acc_tn) {
01978 acc_tn = Get_New_AccTN();
01979 Build_OP(TOP_c3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
01980 flag = 1;
01981 }
01982 Build_OP(top, result, acc_tn, acm, uimm5, ops);
01983
01984 if (flag & 1) {
01985 Erase_AccTN(acc_tn);
01986 }
01987 return result;
01988 }
01989
01990
01991 TN *Expand_C3_FFE(WN *intrncall, TN *result, OPS *ops) {
01992 TN *op1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01993 TN *op2 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01994 TN *mode = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01995 Build_OP(TOP_c3_ffe, op1, op1, op2, mode, ops);
01996 return op1;
01997 }
01998
01999
02000 TN *Expand_C3_lead(WN *intrncall, TN *result, OPS *ops) {
02001 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02002 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
02003 TN *acc_tn = Get_Acc_from_Varidx(v1);
02004 TN *tmp0 = Gen_Literal_TN(0, 4);
02005 INT32 flag = -1;
02006 if (!acc_tn) {
02007 acc_tn = Get_New_AccTN();
02008 Build_OP(TOP_c3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
02009 flag = 1;
02010 }
02011
02012 Build_OP(TOP_c3_lead, result, acc_tn, ops);
02013
02014 if (flag & 1) {
02015 Erase_AccTN(acc_tn);
02016 }
02017 return result;
02018 }
02019
02020
02021
02022 TN *Expand_C3_revb(WN *intrncall, TN *result, OPS *ops) {
02023 TN *op1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02024 TN *mode = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02025 Build_OP(TOP_c3_revb, op1, op1, mode, ops);
02026 return op1;
02027 }
02028
02029
02030 TN *Expand_C3_saadda_a(WN *intrncall, TN *result, OPS *ops) {
02031 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02032 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02033 TN *as1_kid1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
02034 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
02035 TN *uimm4 = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
02036 TN *mode = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);
02037 TN *n = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6)), 4);
02038 TN *m = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 7)), 4);
02039 TN *tmp0 = Gen_Literal_TN(0, 4);
02040 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
02041 TN *acc_tn = Get_Acc_from_Varidx(v1);
02042 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 2);
02043 TN *add1_tn = Get_Addr_from_Varidx(v2);
02044 UINT32 flag = 0;
02045
02046 if (!acc_tn) {
02047 acc_tn = Get_New_AccTN();
02048 Build_OP(TOP_c3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
02049 flag = 1;
02050 } else {
02051 Set_Var_AccTN(AccPregN, acc_tn);
02052 }
02053 if (!add1_tn) {
02054 add1_tn = Get_New_AddrTN();
02055 Build_OP(TOP_c3_mvtaddr, add1_tn, as1_kid1, tmp0, ops);
02056 flag |= 2;
02057 }
02058
02059 Build_OP(TOP_c3_sadda_a, acc_tn, add1_tn, acm, add1_tn, am1, uimm4, mode, n, m, acc_tn, ops);
02060
02061 Set_OP_To_WN_Map(intrncall);
02062
02063 if (flag & 1) {
02064 Build_OP(TOP_c3_mvfacc, result, acc_tn, tmp0, ops);
02065 Erase_AccTN(acc_tn);
02066 }
02067
02068 if (flag & 2) {
02069 Build_OP(TOP_c3_mvfaddr, as1_kid1, add1_tn, tmp0, ops);
02070 Erase_AddrTN(add1_tn);
02071 }
02072 return result;
02073 }
02074
02075
02076 TN *Expand_C3_subc(WN *intrncall, TN *result, OPS *ops) {
02077 TN *op1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02078 TN *op2 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
02079 TN *tmp0 = Gen_Literal_TN(0, 4);
02080 TN *tmp = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
02081
02082 Build_OP(TOP_c3_subc, HI_TN, op1, op1, op2, HI_TN, ops);
02083 Exp_COPY(result, op1, ops);
02084 return result;
02085 }
02086
02087
02088 TN *Expand_C3_nega(WN *intrncall, TN *result, OPS *ops) {
02089 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall)),
02090 ("Sl1_nega:arguments are incomplete"));
02091
02092 TN *accd = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02093 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02094 TN *accs = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
02095 TN *m = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
02096
02097 UINT flag= 0;
02098 TN *tmp0 = Gen_Literal_TN(0, 4);
02099 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
02100 TN *accd_tn = Get_Acc_from_Varidx(v1);
02101 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 2);
02102 TN *accs_tn = Get_Acc_from_Varidx(v2);
02103
02104 if (!accd_tn) {
02105 accd_tn = Get_New_AccTN();
02106 Build_OP(TOP_c3_mvtacc, accd_tn, accd, tmp0, ops);
02107 flag = 1;
02108 } else {
02109 Set_Var_AccTN(AccPregN, accd_tn);
02110 }
02111 if (!accs_tn) {
02112 accs_tn = Get_New_AccTN();
02113 Build_OP(TOP_c3_mvtacc, accs_tn, accs, tmp0, ops);
02114 flag |=2;
02115 }
02116 Build_OP(TOP_c3_nega, accd_tn, acm, accs_tn, m, ops);
02117
02118 if (flag & 1) {
02119 Build_OP(TOP_c3_mvfacc, result, accd_tn, tmp0, ops);
02120 Erase_AccTN(accd_tn);
02121 }
02122 if (flag & 2) {
02123 Erase_AccTN(accs_tn);
02124 }
02125 return result;
02126 }
02127
02128
02129 TN *Expand_C3_mul(TOP top, WN *intrncall, TN *result, OPS *ops) {
02130 TN *op1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02131 TN *op2 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
02132 TN *uimm5 = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
02133 TN *hi = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
02134 INT32 value = -1;
02135 if (TN_has_value(hi)) {
02136 value = TN_value(hi);
02137 } else {
02138 Is_True(0, ("hi_bit should be 0/1"));
02139 }
02140
02141
02142 TN *tmp0 = Gen_Literal_TN(0, 4);
02143 TN *tmp = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
02144
02145 Build_OP(top, HI_TN, tmp, op1, op2, uimm5, ops);
02146 if (value == 1)
02147 Build_OP(TOP_c3_mvfs, result, HI_TN, tmp0, ops);
02148 else
02149 Exp_COPY(result, tmp, ops);
02150
02151 return result;
02152 }
02153
02154
02155 TN *Expand_Init_HI(WN *intrncall, TN *result, OPS *ops) {
02156 TN *rs1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02157 TN *uimm5 = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02158
02159 TOP top = TOP_c3_mvts;
02160 Build_OP(top, HI_TN, rs1, uimm5, ops);
02161 return HI_TN;
02162
02163 }
02164
02165 TN *Expand_Copy_HI(WN *intrncall, TN *result, OPS *ops) {
02166 TN *rs1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02167 TN *uimm5 = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02168 TOP top = TOP_c3_mvfs;
02169 Build_OP(top, result, HI_TN, uimm5, ops);
02170 return result;
02171 }
02172
02173