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
00043
00044 OP *Fixup_OP(TOP top, TN *op1) {
00045 char asm_string[256];
00046
00047 switch (top) {
00048 case TOP_c3_viterbi:
00049 sprintf(asm_string, "ldw $0, 0(%0)");
00050 break;
00051 default:
00052 Is_True(0, ("unsupport op to be fixed up"));
00053 }
00054 TN *opnd[1];
00055 opnd[0] = op1;
00056 OP *asm_op = Mk_VarOP(TOP_asm, 0, 1, NULL, opnd);
00057 Set_OP_volatile(asm_op);
00058 ASM_OP_ANNOT* asm_info = TYPE_PU_ALLOC(ASM_OP_ANNOT);
00059 bzero(asm_info, sizeof(ASM_OP_ANNOT));
00060 WN *asm_wn = WN_CreateAsm_Stmt (1, asm_string);
00061 ASM_OP_wn(asm_info) = asm_wn;
00062 OP_MAP_Set(OP_Asm_Map, asm_op, asm_info);
00063 return asm_op;
00064 }
00065
00066
00067 void Print_Acc (TN *acctn) {
00068 typedef std::map<INT32, TN*> Var2Acc;
00069 Var2Acc::iterator it = var2acc.begin();
00070 fprintf(TFile, "ACC[%d] --> ", (TN_number(acctn) - 271));
00071 for(;it != var2acc.end();++it) {
00072 if ((*it).second == acctn) {
00073 if ((*it).first >= 0)
00074 fprintf(TFile, " GPR[%d] ", (*it).first);
00075 else
00076 fprintf(TFile, " ST [%s] ", ST_name(-(*it).first));
00077 }
00078 }
00079 fprintf(stdout, "\n");
00080 }
00081
00082
00083 void Print_Addr (TN *addrtn) {
00084 typedef std::map<INT32, TN*> Var2Addr;
00085 Var2Addr::iterator it = var2addr.begin();
00086 fprintf(TFile, "ADDR[%d] --> ", (TN_number(addrtn) - 275));
00087 for(;it != var2addr.end();++it)
00088 {
00089 if ((*it).second == addrtn) {
00090 if ((*it).first >= 0)
00091 fprintf(TFile, " GPR[%d] ", (*it).first);
00092 else
00093 fprintf(TFile, " ST [%s] ", ST_name(-(*it).first));
00094 }
00095 }
00096 fprintf(stdout, "\n");
00097 }
00098
00099
00100
00101 void Initial_var2spe() {
00102 if (var2acc.size() > 0) {
00103 typedef std::map<INT32, TN*> Var2Acc;
00104 Var2Acc::iterator it = var2acc.begin();
00105 for(;it != var2acc.end();++it)
00106 {
00107 var2acc.erase((*it).first);
00108 }
00109 }
00110 if (var2addr.size() > 0) {
00111 typedef std::map<INT32, TN*> Var2Addr;
00112 Var2Addr::iterator it = var2addr.begin();
00113 for(;it != var2addr.end();++it)
00114 {
00115 var2addr.erase((*it).first);
00116 }
00117 }
00118 return;
00119 }
00120
00121 static BOOL Has_VarWN_idx(WN *stmt) {
00122 Is_True(WN_operator(stmt) == OPR_STID, ("statement should be stid "));
00123 if (WN_class(stmt) == CLASS_PREG) {
00124 if (WN_operator(stmt) == OPR_STID) {
00125 return TRUE;
00126 }
00127 } else if (WN_class(stmt) == CLASS_VAR) {
00128 return TRUE;
00129 }
00130 return FALSE;
00131 }
00132
00133
00134
00135
00136
00137 static INT Get_VarWN_idx (WN *stmt) {
00138
00139 Is_True(WN_operator(stmt) == OPR_STID || WN_operator(stmt) == OPR_LDID, ("stid or ldid"));
00140
00141 if (WN_class(stmt) == CLASS_PREG) {
00142 if (WN_operator(stmt) == OPR_STID )
00143 return WN_store_offset(stmt);
00144 else if (WN_operator(stmt) == OPR_LDID)
00145 return WN_load_offset(stmt);
00146 } else if (WN_class(stmt) == CLASS_VAR) {
00147 return (-WN_st_idx(stmt));
00148 } else {
00149 Is_True(0, ("NYI"));
00150 }
00151 }
00152
00153
00154
00155
00156 void Set_IntrnOP_Result (WN *stid) {
00157 if (WN_operator(WN_kid0(stid)) == OPR_INTRINSIC_OP ) {
00158 INTRINSIC id = (INTRINSIC) WN_intrinsic (WN_kid0(stid));
00159
00160 if (id >= INTRN_C3_INTRINSIC_BEGIN && id <= INTRN_C3_INTRINSIC_END) {
00161 if (id == INTRN_C3_PTR)
00162 AddPregN = Get_VarWN_idx(stid);
00163 else
00164 AccPregN = Get_VarWN_idx(stid);
00165 }
00166 }
00167 return;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 TN *Get_Liternal_TN (WN *wn, INT size) {
00179 INT val=0;
00180 if (WN_operator(wn) == OPR_INTCONST) {
00181 val = WN_const_val(wn);
00182 } else {
00183 Is_True(WN_class(wn) == CLASS_PREG, ("WN should be PREG variable"));
00184 WN *home = Preg_Home(WN_load_offset(wn));
00185 if (!home) {
00186 Is_True(0, ("WN should be immediate"));
00187 }
00188 Is_True(WN_operator(home) == OPR_INTCONST, ("WN should be immediate"));
00189 val = WN_const_val(home);
00190 }
00191 return Gen_Literal_TN(val, size);
00192 }
00193
00194
00195
00196 static INT TN_To_Index(TN *tn) {
00197 if (TN_is_symbol(tn)) {
00198 Is_True(TN_var(tn), ("symbol tn should have var"));
00199 return (-TN_var(tn)->st_idx);
00200 }
00201 else
00202 return TN_To_PREG(tn);
00203 }
00204
00205
00206
00207
00208
00209 void Copy_Tn_MapInfo(TN *src_tn, TN *tgt_tn) {
00210 if ( TN_register_class(tgt_tn) == TN_register_class(src_tn)) {
00211 INT32 srcpreg = TN_To_Index(src_tn);
00212 if ((var2acc.size() > 0) && var2acc[srcpreg]) {
00213 INT32 tgtpreg = TN_To_Index(tgt_tn);
00214 var2acc[tgtpreg] = var2acc[srcpreg];
00215 if (dotrace) {
00216 fprintf(TFile, "EXP_COPY::");
00217 Print_Acc(var2acc[srcpreg]);
00218 }
00219 }
00220 else if ((var2addr.size() > 0) && var2addr[srcpreg]) {
00221 INT32 tgtpreg = TN_To_Index(tgt_tn);
00222 var2addr[tgtpreg] = var2addr[srcpreg];
00223 if (dotrace) {
00224 fprintf(TFile, "EXP_COPY::");
00225 Print_Addr(var2addr[srcpreg]);
00226 }
00227 }
00228 }
00229 }
00230
00231
00232
00233
00234
00235 void Copy_Preg_MapInfo(WN *stid) {
00236 WN *ldid = WN_kid0(stid);
00237 if (WN_operator(ldid) != OPR_LDID ) {
00238 return;
00239 }
00240 Is_True(WN_operator(ldid) == OPR_LDID, ("ldid"));
00241 if (!(WN_class(ldid) == CLASS_PREG) && !(WN_class(ldid) == CLASS_VAR)) {
00242 return;
00243 }
00244 INT32 srcpreg = Get_VarWN_idx(ldid);
00245
00246 INT32 tgtpreg;
00247 if (Has_VarWN_idx(stid)) {
00248 tgtpreg = Get_VarWN_idx(stid);
00249 if (var2acc[tgtpreg]) {
00250 var2acc[srcpreg] = var2acc[tgtpreg];
00251 if (dotrace) {
00252 fprintf(stdout, "HANDLE_STID::");
00253 Print_Acc(var2acc[tgtpreg]);
00254 }
00255 } else if (var2addr[tgtpreg]) {
00256 var2addr[srcpreg] = var2addr[tgtpreg];
00257 if (dotrace) {
00258 fprintf(stdout, "HANDLE_STID::");
00259 Print_Addr(var2addr[tgtpreg]);
00260 }
00261 } else if (var2acc[srcpreg]) {
00262 tgtpreg = Get_VarWN_idx(stid);
00263 var2acc[tgtpreg] = var2acc[srcpreg];
00264 if (dotrace) {
00265 fprintf(stdout, "HANDLE_STID::");
00266 Print_Acc(var2acc[srcpreg]);
00267 }
00268 } else if (var2addr[srcpreg]) {
00269 tgtpreg = Get_VarWN_idx(stid);
00270 var2addr[tgtpreg] = var2addr[srcpreg];
00271 if (dotrace) {
00272 fprintf(stdout, "HANDLE_STID::");
00273 Print_Addr(var2addr[srcpreg]);
00274 }
00275 }
00276 }
00277 }
00278
00279 static INT32 Get_ParmVaridx_Intrncall(WN *intrncall, int kidnum=0) {
00280
00281 WN *para_wn = WN_kid0(WN_kid(intrncall, kidnum));
00282 OPERATOR opr = WN_operator(para_wn) ;
00283 if (opr== OPR_LDID) {
00284 return Get_VarWN_idx(para_wn);
00285 } else if (opr == OPR_INTRINSIC_OP) {
00286 INTRINSIC id = (INTRINSIC) WN_intrinsic (para_wn);
00287 if ((id >= INTRN_C3_INTRINSIC_BEGIN) && (id <= INTRN_C3_INTRINSIC_END)) {
00288 if (id == INTRN_C3_PTR)
00289 return Get_ParmVaridx_Intrncall(para_wn, 1);
00290 else
00291 return Get_ParmVaridx_Intrncall(para_wn);
00292 } else {
00293 Is_True(0, ("WN must be c3 intrinsic "));
00294 }
00295
00296 }
00297 return 0;
00298
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 static INT32 Get_ResultEqVarIdx ( WN *istore) {
00319 Is_True(WN_operator(istore) == OPR_ISTORE , ("operator must be istore")) ;
00320
00321 WN *next = WN_next(istore);
00322 INT32 varidx = Get_VarWN_idx(WN_kid1(istore));
00323 WN_OFFSET addroff = WN_offset(istore);
00324
00325 while(next) {
00326 if ((WN_operator(next) == OPR_STID) &&
00327 (WN_operator(WN_kid0(next)) == OPR_ILOAD)) {
00328 WN *load = WN_kid0(next);
00329 if ((varidx == Get_VarWN_idx(WN_kid0(load))) && (addroff == WN_offset(load)))
00330 return Get_VarWN_idx(next);
00331 }
00332 next = WN_next(next);
00333 }
00334
00335 if (!next) {
00336 if (WN_operator(WN_kid0(istore)) == OPR_LDID) {
00337 return Get_VarWN_idx(WN_kid0(istore));
00338 } else {
00339 DevWarn("init special register is undefined");
00340 return -1;
00341 }
00342 }
00343
00344 }
00345
00346 static INT32 Get_Resultidx_Intrncall (WN *intrncall) {
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 WN *next= WN_next(intrncall);
00357 WN *retval = WN_kid0(next);
00358
00359 Is_True(next && (WN_operator(next) == OPR_STID),
00360 ("intrnsic call should have result"));
00361 Is_True((WN_operator(retval) == OPR_LDID) && (ST_class(WN_st(retval)) == CLASS_PREG) &&
00362 (WN_offset(retval) == First_Int_Preg_Return_Offset),
00363 ("intrnsic call should have result tn"));
00364
00365
00366
00367 INT32 tmp_idx = Get_VarWN_idx(next);
00368
00369 if (strcmp(ST_name(WN_st(next)) , "__comma") != 0) {
00370 next = WN_next(next);
00371 }
00372
00373 while (next) {
00374 if (WN_operator(next) == OPR_STID &&
00375 (WN_operator(WN_kid0(next))==OPR_LDID) &&
00376 (tmp_idx == Get_VarWN_idx(WN_kid0(next)))) {
00377 PREG_NUM tmppn= Get_VarWN_idx(next);
00378 if (tmppn > 11 || tmppn < 4)
00379 break;
00380 }
00381 if (WN_operator(next) == OPR_ISTORE &&
00382 (WN_operator(WN_kid0(next)) == OPR_LDID) &&
00383 (tmp_idx == Get_VarWN_idx(WN_kid0(next)))) {
00384 return Get_ResultEqVarIdx(next);
00385 }
00386 next = WN_next(next);
00387 }
00388
00389 if (!next) {
00390 return tmp_idx;
00391 }
00392
00393 return Get_VarWN_idx(next);
00394
00395 }
00396
00397
00398 static TN *Get_New_AccTN () {
00399 TN *acctn=NULL;
00400 int i;
00401 for(i = prev_alloc_AccIndex; i < (prev_alloc_AccIndex + CG_Max_Accreg); i++) {
00402 if (ACCreg[i%CG_Max_Accreg] == 0) {
00403 switch (i%CG_Max_Accreg) {
00404 case 0 : acctn = Acc0_TN ; ACCreg[0]=1; break;
00405 case 1 : acctn = Acc1_TN ; ACCreg[1]=1; break;
00406 case 2 : acctn = Acc2_TN ; ACCreg[2]=1; break;
00407 case 3 : acctn = Acc3_TN; ACCreg[3]=1; break;
00408 default: Is_True(0,("illegal acc register tn"));
00409 }
00410 }
00411 if (acctn) break;
00412 }
00413
00414 if (i == (prev_alloc_AccIndex + CG_Max_Accreg))
00415 Is_True(0, ("No valid new acc register, max acc register numbers is %d\n", CG_Max_Accreg));
00416 if (CG_round_spreg)
00417 prev_alloc_AccIndex = (i+1)%CG_Max_Accreg;
00418 return acctn;
00419 }
00420
00421 static TN *Create_Var2Acc_Map(INT32 varidx) {
00422 INT i;
00423 TN *acctn = NULL;
00424 if (var2acc.size() > 0)
00425 acctn = var2acc[varidx];
00426
00427 Is_True(!acctn, ("variable has acquired an acc register and did't free it"));
00428 acctn = Get_New_AccTN();
00429 var2acc[varidx] = acctn;
00430
00431 if (dotrace) {
00432 fprintf(TFile, "Create_Var2Acc_Map::");
00433 Print_Acc(acctn);
00434 }
00435 return acctn;
00436 }
00437
00438
00439 static TN *Get_New_DualAccTN () {
00440 TN *acctn=NULL;
00441 int i;
00442 if (prev_alloc_AccIndex %2 !=0 ) {
00443 prev_alloc_AccIndex = (prev_alloc_AccIndex+1)%CG_Max_Accreg;
00444 }
00445 for(i = prev_alloc_AccIndex; i < (prev_alloc_AccIndex + CG_Max_Accreg); i=i+2) {
00446 if ((ACCreg[i%CG_Max_Accreg] == 0) && (ACCreg[(i+1)%CG_Max_Accreg] == 0)) {
00447 switch (i%CG_Max_Accreg) {
00448 case 0 : acctn = Acc0_TN ; ACCreg[0]=1; ACCreg[1]=1;break;
00449 case 2 : acctn = Acc2_TN ; ACCreg[2]=1; ACCreg[3]=1; break;
00450 default: Is_True(0,("Get_New_DualAccTN::illegal acc register tn"));
00451 }
00452 }
00453 if (acctn) break;
00454 }
00455
00456 if (!acctn || (CG_Max_Accreg < 2) || (CG_Max_Accreg == 3 && ACCreg[3]==1))
00457 Is_True(0, ("NO valid dual acc registers, max acc register numbers are %d\n", CG_Max_Accreg));
00458
00459 if (CG_round_spreg)
00460 prev_alloc_AccIndex = (i+2)%CG_Max_Accreg;
00461
00462 return acctn;
00463 }
00464
00465 static TN *Create_Var2DualAcc_Map(INT32 varidx) {
00466 INT i;
00467 TN *acctn = NULL;
00468 if(var2acc.size() > 0)
00469 acctn = var2acc[varidx];
00470 Is_True(!acctn, ("variable has acquired an acc register and didn't free it"));
00471 acctn = Get_New_DualAccTN();
00472 var2acc[varidx] = acctn;
00473
00474 if (dotrace) {
00475 fprintf(TFile, "Create_Var2DAcc_Map::");
00476 Print_Acc(acctn);
00477 }
00478 return acctn;
00479 }
00480
00481
00482 static TN *Get_New_AddrTN () {
00483 TN *addtn=NULL;
00484 int i;
00485 for(i = prev_alloc_AddrIndex; i < (prev_alloc_AddrIndex + CG_Max_Addreg); i++) {
00486 if (Addreg[i%CG_Max_Addreg] == 0) {
00487 switch (i%CG_Max_Addreg) {
00488 case 0 : addtn = Addr0_TN ; Addreg[0]=1; break;
00489 case 1 : addtn = Addr1_TN ; Addreg[1]=1; break;
00490 case 2 : addtn = Addr2_TN ; Addreg[2]=1; break;
00491 case 3 : addtn = Addr3_TN; Addreg[3]=1; break;
00492 case 4 : addtn = Addr4_TN; Addreg[4]=1; break;
00493 case 5 : addtn = Addr5_TN; Addreg[5]=1; break;
00494 case 6 : addtn = Addr6_TN; Addreg[6]=1; break;
00495 case 7 : addtn = Addr7_TN; Addreg[7]=1; break;
00496 default: Is_True(0,("illegal address register tn"));
00497 }
00498 }
00499 if (addtn) break;
00500 }
00501
00502 if (i == (prev_alloc_AddrIndex + CG_Max_Addreg))
00503 Is_True(0, ("No valid new address register, max address register numbers is %d\n", CG_Max_Addreg));
00504 if (CG_round_spreg)
00505 prev_alloc_AddrIndex = (i+1)%CG_Max_Addreg;
00506 return addtn;
00507 }
00508
00509 static TN * Get_AddrSize_Reg(TN *addrtn) {
00510 TN *addr_size = NULL;
00511
00512 if (addrtn == Addr0_TN)
00513 addr_size = Addrsize0_TN;
00514 else if (addrtn == Addr1_TN)
00515 addr_size = Addrsize1_TN;
00516 else if (addrtn == Addr2_TN)
00517 addr_size = Addrsize2_TN;
00518 else if (addrtn == Addr3_TN)
00519 addr_size = Addrsize3_TN;
00520 else if (addrtn == Addr4_TN)
00521 addr_size = Addrsize4_TN;
00522 else if (addrtn == Addr5_TN)
00523 addr_size = Addrsize5_TN;
00524 else if (addrtn == Addr6_TN)
00525 addr_size = Addrsize6_TN;
00526 else if (addrtn == Addr7_TN)
00527 addr_size = Addrsize7_TN;
00528 return addr_size;
00529 }
00530
00531 static TN *Create_Var2Add_Map(INT32 varidx) {
00532 INT i;
00533 TN *addrtn = NULL;
00534 if(var2addr.size() > 0)
00535 addrtn = var2addr[varidx];
00536
00537 Is_True(!addrtn, ("addrtn should be null"));
00538 addrtn = Get_New_AddrTN();
00539 var2addr[varidx] = addrtn;
00540 if(dotrace) {
00541 fprintf(TFile, "Create_Var2Add_Map::");
00542 Print_Addr(addrtn);
00543 }
00544 return addrtn;
00545 }
00546
00547
00548 static inline void Set_Var_AccTN ( INT32 varidx, TN *acctn) {
00549 var2acc[varidx] = acctn;
00550 if (dotrace) {
00551 Print_Acc(acctn);
00552 }
00553 }
00554
00555 static inline void Set_Var_AddrTN ( INT32 varidx, TN *addtn) {
00556 var2addr[varidx] = addtn;
00557 if (dotrace) {
00558 Print_Addr(addtn);
00559 }
00560 }
00561
00562
00563 static TN *Get_Acc_from_Varidx(INT32 varidx) {
00564 if ((var2acc.size() > 0) && var2acc[varidx]) {
00565 return var2acc[varidx];
00566 } else
00567 return NULL;
00568 }
00569
00570 static TN *Get_Addr_from_Varidx(INT32 varidx) {
00571 if ((var2addr.size() > 0) && var2addr[varidx]) {
00572 return var2addr[varidx];
00573 }
00574 else
00575 return NULL;
00576 }
00577
00578 static void Erase_AccTN (TN *acctn) {
00579 if (acctn == Acc0_TN)
00580 ACCreg[0] = 0;
00581 else if (acctn == Acc1_TN)
00582 ACCreg[1] = 0;
00583 else if (acctn == Acc2_TN)
00584 ACCreg[2] = 0;
00585 else if (acctn == Acc3_TN)
00586 ACCreg[3] = 0;
00587 else
00588 Is_True(0, ("tn is not a valie acc register tn"));
00589
00590 return;
00591 }
00592
00593
00594
00595 static void Erase_Var2Acc_Map(INT32 varidx) {
00596 TN *acctn = Get_Acc_from_Varidx(varidx);
00597 Is_True(acctn, ("acctn are not used or has been freed before "));
00598
00599 if(dotrace) {
00600 fprintf(TFile, "Erase_Var2Acc_Map:: ");
00601 Print_Acc(acctn);
00602 }
00603 Erase_AccTN(acctn);
00604
00605 typedef std::map<INT32, TN*> Var2Acc;
00606 Var2Acc::iterator it = var2acc.begin();
00607 for(;it != var2acc.end();++it)
00608 {
00609 if ((*it).second == acctn) {
00610 var2acc.erase((*it).first);
00611 }
00612 }
00613 return;
00614 }
00615
00616
00617
00618
00619 static TN *Get_DualAccTN (TN *acc_tn) {
00620 TN *dacc_tn ;
00621 if (acc_tn == Acc0_TN)
00622 dacc_tn = Acc1_TN;
00623 else if (acc_tn == Acc2_TN)
00624 dacc_tn = Acc3_TN;
00625 else if (acc_tn == Acc3_TN || acc_tn == Acc1_TN)
00626 Is_True(0, ("first dual acc register should be even index"));
00627 else {
00628 Is_True(0, ("dual acc register is not valid"));
00629 }
00630 return dacc_tn;
00631 }
00632
00633
00634 static void Erase_Var2DualAcc_Map(INT32 varidx) {
00635 TN *acctn = Get_Acc_from_Varidx(varidx);
00636 Is_True(acctn, ("dual acctn are not used or have been free before"));
00637 TN *dacctn = Get_DualAccTN(acctn);
00638
00639 if(dotrace) {
00640 fprintf(TFile, "Erase_Var2DualAcc_Map ");
00641 Print_Acc(acctn);
00642 fprintf(TFile, "Erase_Var2DualAcc_Map ");
00643 Print_Acc(dacctn);
00644 }
00645 Erase_AccTN(acctn);
00646 Erase_AccTN(dacctn);
00647
00648 typedef std::map<INT32, TN*> Var2Acc;
00649 Var2Acc::iterator it = var2acc.begin();
00650 for(;it != var2acc.end();++it)
00651 {
00652 if (((*it).second == acctn) || ((*it).second == dacctn)) {
00653 var2acc.erase((*it).first);
00654 }
00655 }
00656 return;
00657 }
00658
00659
00660 static void Erase_AddrTN (TN *addrtn) {
00661
00662 if (addrtn == Addr0_TN)
00663 Addreg[0] = 0;
00664 else if (addrtn == Addr1_TN)
00665 Addreg[1] = 0;
00666 else if (addrtn == Addr2_TN)
00667 Addreg[2] = 0;
00668 else if (addrtn == Addr3_TN)
00669 Addreg[3] = 0;
00670 else if (addrtn == Addr4_TN)
00671 Addreg[4] = 0;
00672 else if (addrtn == Addr5_TN)
00673 Addreg[5] = 0;
00674 else if (addrtn == Addr6_TN)
00675 Addreg[6] = 0;
00676 else if (addrtn == Addr7_TN)
00677 Addreg[7] = 0;
00678 else
00679 Is_True(0, ("addrtn is not a valid address register tn"));
00680 return;
00681 }
00682
00683
00684 static void Erase_Var2Addr_Map(INT32 varidx) {
00685 TN *addtn = Get_Addr_from_Varidx(varidx);
00686 Is_True(addtn, ("address register is not used or has been free before"));
00687
00688 if (dotrace) {
00689 fprintf(TFile, "Erase_Var2Addr_Map:: ");
00690 Print_Addr(addtn);
00691 }
00692 Erase_AddrTN(addtn);
00693
00694
00695 typedef std::map<INT32, TN*> Var2Addr;
00696 Var2Addr::iterator it = var2addr.begin();
00697 for(;it != var2addr.end();++it)
00698 {
00699 if ((*it).second == addtn) {
00700 var2addr.erase((*it).first);
00701 }
00702 }
00703 return;
00704 }
00705
00706
00707
00708
00709
00710
00711
00712 TN *Expand_C3_INIT_ACC (WN *intrncall, TN *result, OPS *ops) {
00713
00714 Is_True(WN_kid0(intrncall), ("sl1_l_acquire_acc: 1 argument is null"));
00715 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00716 TN *shl_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
00717 INT32 pregn = Get_Resultidx_Intrncall(intrncall);
00718 TN *acc_tn = Create_Var2Acc_Map(pregn);
00719 Build_OP(TOP_c3_mvtacc, acc_tn, kid0_tn, shl_tn, ops);
00720
00721 return kid0_tn;
00722 }
00723
00724
00725
00726
00727
00728
00729
00730 TN *Expand_C3_SAVE_ACC (WN *intrncall, TN *result, OPS *ops) {
00731
00732 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall), ("sl1_l_free_acc: argument is null"));
00733 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
00734 TN *shr_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
00735 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
00736 TN *acctn = Get_Acc_from_Varidx(varidx);
00737 Is_True(acctn, ("variable hasn't acquired acc register"));
00738
00739 if (!result) {
00740 result = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
00741 }
00742 Build_OP(TOP_c3_mvfacc, result, acctn, shr_tn, ops);
00743
00744 Erase_Var2Acc_Map(varidx);
00745
00746 return result;
00747
00748 }
00749
00750 TN *Expand_C3_MAC(WN *intrncall, TN *result, OPS *ops, BOOL ismac=TRUE) {
00751 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall)),
00752 ("sl1_mac: argument is null"));
00753
00754 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00755 TN *kid1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
00756 TN *kid2_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
00757 TN *acmode = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
00758 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
00759 TN *acctn = Get_Acc_from_Varidx(varidx);
00760
00761
00762 if (acctn)
00763 Set_Var_AccTN(AccPregN, acctn);
00764
00765 TOP top = ismac ? TOP_c3_mac: TOP_c3_macn;
00766 if (acctn) {
00767 Build_OP(top, acctn, acmode, kid1_tn, kid2_tn, acctn, ops);
00768 } else {
00769 acctn = Get_New_AccTN();
00770 Build_OP(TOP_c3_mvtacc, acctn, kid0_tn,Gen_Literal_TN(0,4), ops);
00771 Build_OP(top, acctn, acmode, kid1_tn, kid2_tn, acctn, ops);
00772 Build_OP(TOP_c3_mvfacc, result, acctn, Gen_Literal_TN(0,4), ops);
00773 Erase_AccTN(acctn);
00774 }
00775 return result;
00776 }
00777
00778
00779 TN *Expand_C3_ROUND (WN *intrncall, TN *result, OPS *ops) {
00780 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall),
00781 ("sl1_shl_round_shr: argument is null"));
00782 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00783 TN *shl_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
00784 TN *acmode = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
00785 TN *shr_tn = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
00786 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
00787 TN *acctn = Get_Acc_from_Varidx(varidx);
00788
00789 if (acctn) {
00790 Is_True(TN_value(shr_tn) == 0, ("sl1_shl_round_shr: the last parameter must be zero"));
00791 Set_Var_AccTN(AccPregN, acctn);
00792 Build_OP(TOP_c3_round, acctn, shl_tn, acmode, acctn, ops);
00793 } else {
00794 acctn = Get_New_AccTN();
00795 Build_OP(TOP_c3_mvtacc, acctn, kid0_tn, Gen_Literal_TN(0,4), ops);
00796 Build_OP(TOP_c3_round, acctn, shl_tn, acmode, acctn, ops);
00797 Build_OP(TOP_c3_mvfacc, result, acctn, shr_tn, ops);
00798 Erase_AccTN(acctn);
00799 }
00800 return result;
00801 }
00802
00803 TN *Expand_C3_SAADDS(WN *intrncall, TN *result, OPS *ops, BOOL isadd= TRUE) {
00804
00805 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall)),
00806 ("sl1_saadds: argument is null"));
00807 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00808 TN *kid1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
00809 TN *kid2_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
00810 TOP top = isadd ? TOP_c3_saadds: TOP_c3_sasubs;
00811
00812 Build_OP(top, result, kid0_tn, kid1_tn, kid2_tn, ops);
00813 return result;
00814 }
00815
00816 TN *Expand_C3_MULA (WN *intrncall, TN *result, OPS *ops) {
00817
00818 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall)),
00819 ("sl1_l_mula: argument is null"));
00820 TN *kidtn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00821 TN *kid0_tn = Expand_Expr (WN_kid1(intrncall), intrncall, NULL);
00822 TN *kid1_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
00823 TN *accmode = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
00824 TN *shiftnum = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
00825
00826 TOP top = TOP_c3_mula;
00827 TN *acctn = NULL;
00828 if (TN_has_value(kidtn) || WN_operator(WN_kid0(WN_kid0(intrncall))) == OPR_INTCONST) {
00829 acctn = NULL;
00830 } else {
00831 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
00832 acctn = Get_Acc_from_Varidx(varidx);
00833 }
00834 if (acctn) {
00835 Is_True(TN_value(shiftnum) == 0, ("sl1_l_mula :: shiftnum should be zero"));
00836 Set_Var_AccTN(AccPregN, acctn);
00837 Build_OP(top, acctn, accmode, kid0_tn, kid1_tn, ops);
00838 }else {
00839 acctn = Get_New_AccTN();
00840 Build_OP(top, acctn, accmode, kid0_tn, kid1_tn, ops);
00841 Build_OP(TOP_c3_mvfacc, result, acctn, shiftnum, ops);
00842 Erase_AccTN(acctn);
00843 }
00844 return result;
00845 }
00846
00847
00848
00849
00850 TN *Expand_MPY_32_16 (WN *intrncall, TN *result, OPS *ops) {
00851
00852 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall),
00853 ("Expand_MPY_32_16:: operand is null"));
00854
00855 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00856 TN *kid1_tn = Expand_Expr (WN_kid1(intrncall), intrncall, NULL);
00857 TN *kid2_tn = Expand_Expr (WN_kid2(intrncall), intrncall, NULL);
00858
00859
00860
00861
00862
00863
00864
00865 TN *tmp_acc1tn = Get_New_AccTN();
00866 TN *tmp_acc2tn = Get_New_AccTN();
00867 TN *accmode = Gen_Literal_TN(3, 4);
00868 TN *tmp16 = Gen_Literal_TN(16, 4);
00869 TN *tmp1 = Gen_Literal_TN(1, 4);
00870 TN *tmp0 = Gen_Literal_TN(0, 4);
00871 TN *tmptn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
00872 Build_OP(TOP_c3_mula, tmp_acc1tn, accmode, kid0_tn, kid2_tn, ops);
00873 Build_OP(TOP_c3_mula, tmp_acc2tn, accmode, kid1_tn, kid2_tn, ops);
00874 Build_OP(TOP_c3_mvfacc, tmptn, tmp_acc2tn, tmp16, ops);
00875 Build_OP(TOP_c3_mac_i, tmp_acc1tn, accmode, tmptn, tmp1, tmp_acc1tn, ops);
00876 Build_OP(TOP_c3_mvfacc, result, tmp_acc1tn, tmp0, ops);
00877 Erase_AccTN(tmp_acc1tn);
00878 Erase_AccTN(tmp_acc2tn);
00879 return result;
00880 }
00881
00882
00883
00884 TN *Expand_MPY_32 (WN *intrncall, TN *result, OPS *ops) {
00885 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall),
00886 ("Expand_MPY_32_16:: operand is null"));
00887
00888 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00889 TN *kid1_tn = Expand_Expr (WN_kid1(intrncall), intrncall, NULL);
00890 TN *kid2_tn = Expand_Expr (WN_kid2(intrncall), intrncall, NULL);
00891 TN *kid3_tn = Expand_Expr (WN_kid3(intrncall), intrncall, NULL);
00892
00893
00894
00895
00896
00897
00898
00899
00900 TN *tmp_acc1tn = Get_New_AccTN();
00901 TN *accmode = Gen_Literal_TN(3, 4);
00902 TN *tmp16 = Gen_Literal_TN(16, 4);
00903 TN *tmp0 = Gen_Literal_TN(0, 4);
00904 TN *tmptn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
00905 Build_OP(TOP_c3_mula, tmp_acc1tn, accmode, kid0_tn, kid3_tn, ops);
00906 Build_OP(TOP_c3_mac, tmp_acc1tn, accmode, kid1_tn, kid2_tn, tmp_acc1tn, ops);
00907 Build_OP(TOP_c3_mvfacc, tmptn, tmp_acc1tn, tmp16, ops);
00908 Build_OP(TOP_c3_mvtacc, tmp_acc1tn, tmptn, tmp0, ops);
00909 Build_OP(TOP_c3_mac, tmp_acc1tn, accmode, kid0_tn, kid2_tn, tmp_acc1tn, ops);
00910 Build_OP(TOP_c3_mvfacc, result, tmp_acc1tn, tmp0, ops);
00911 Erase_AccTN(tmp_acc1tn);
00912
00913 return result;
00914 }
00915
00916
00917 TN *Expand_C3_MACD(WN *intrncall, TN *result, OPS *ops) {
00918
00919 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall)),
00920 ("sl1_l_macd:: operand is null"));
00921
00922 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00923 TN *kid1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
00924 TN *kid2_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
00925 TN *acmode = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
00926 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
00927 TN *acctn = Get_Acc_from_Varidx(varidx);
00928
00929 if (acctn) {
00930
00931 Set_Var_AccTN(AccPregN, acctn);
00932 Build_OP(TOP_c3_macd, acctn, acmode, kid1_tn, kid2_tn, acctn, ops);
00933 }
00934 else {
00935 acctn = Get_New_AccTN();
00936 Build_OP(TOP_c3_mvtacc, acctn, kid0_tn,Gen_Literal_TN(0,4), ops);
00937 Build_OP(TOP_c3_macd, acctn, acmode, kid1_tn, kid2_tn, acctn, ops);
00938 Build_OP(TOP_c3_mvfacc, result, acctn, Gen_Literal_TN(0,4), ops);
00939 Erase_AccTN(acctn);
00940 }
00941 return result;
00942 }
00943
00944
00945 TN *Expand_C3_MVFS(WN *intrncall, TN *result, OPS *ops) {
00946
00947 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall)),
00948 ("sl1_l_copy_shr_acc: argument is null"));
00949 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00950 TN *shiftnum = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
00951 TN *accid = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
00952 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
00953 TN *acctn = Get_Acc_from_Varidx(varidx);
00954 Is_True(acctn, ("sl1_copy_shr_acc:: argument 1 has not mapped to acc register"));
00955 Is_True(TN_has_value(accid), ("sl1_copy_shr_acc:: arg 3 is not immediate integer"));
00956 if (TN_value(accid) == 1) {
00957 Is_True(Get_DualAccTN(acctn), ("sl1_copy_shr_acc:: arg 1 has not mapped to dual acc register"));
00958 acctn = Get_DualAccTN(acctn);
00959 }
00960 Build_OP(TOP_c3_mvfacc, result, acctn, shiftnum, ops);
00961 return result;
00962 }
00963
00964 TN *Expand_C3_SAADDSH (WN *intrncall, TN *result, OPS *ops, BOOL isadd=TRUE) {
00965
00966 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall)),
00967 ("sl1_saaddsh: arguments are incomplete "));
00968 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
00969 TN *kid1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
00970 TN *kid2_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
00971
00972 TOP top = isadd ? TOP_c3_saaddsh : TOP_c3_sasubsh;
00973 Build_OP(top, result, kid0_tn, kid1_tn, kid2_tn, ops);
00974 return result;
00975 }
00976
00977 TN *Expand_C3_MAC_A (WN *intrncall, TN *result, OPS *ops, BOOL mac_a = TRUE) {
00978
00979 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall) &&
00980 WN_kid(intrncall, 4) && WN_kid(intrncall, 5) && WN_kid(intrncall, 6)),
00981 ("sl1_l_mac_p:: arguments are incomplete"));
00982
00983 TN *acc_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
00984 TN *acmtn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
00985 TN *as1_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
00986 TN *as1_mode = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
00987 TN *as2_tn = Expand_Expr(WN_kid(intrncall, 4), intrncall, NULL);
00988 TN *as2_mode = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);
00989 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6)), 4);
00990 UINT flag= 0;
00991 TN *tmp0 = Gen_Literal_TN(0, 4);
00992 TOP top = mac_a ? TOP_c3_mac_a : TOP_c3_macn_a;
00993 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
00994 TN *acctn = Get_Acc_from_Varidx(varidx);
00995 INT32 varidx1 = Get_ParmVaridx_Intrncall(intrncall, 2);
00996 TN *add1tn = Get_Addr_from_Varidx(varidx1);
00997 INT32 varidx2 = Get_ParmVaridx_Intrncall(intrncall, 4);
00998 TN *add2tn = Get_Addr_from_Varidx(varidx2);
00999
01000 if (acctn)
01001 Set_Var_AccTN(AccPregN, acctn);
01002 if (!acctn) {
01003 acctn = Get_New_AccTN();
01004 Build_OP(TOP_c3_mvtacc, acctn, acc_tn, tmp0, ops);
01005 flag = 1;
01006 }
01007 if (!add1tn) {
01008 add1tn = Get_New_AddrTN();
01009 Build_OP(TOP_c3_mvtadd, add1tn, as1_tn, tmp0, ops);
01010 flag |=2;
01011 }
01012 if (!add2tn) {
01013 add2tn = Get_New_AddrTN();
01014 Build_OP(TOP_c3_mvtadd, add2tn, as2_tn, tmp0, ops);
01015 flag |=4;
01016 }
01017 Build_OP(top, acctn, add1tn, add2tn, acmtn, add1tn, as1_mode, add2tn, as2_mode, bsel_tn, acctn, ops);
01018 Set_OP_To_WN_Map(intrncall);
01019
01020 if (flag & 1) {
01021 Build_OP(TOP_c3_mvfacc, result, acctn, tmp0, ops);
01022 Erase_AccTN(acctn);
01023 }
01024 if (flag & 2) {
01025 Build_OP(TOP_c3_mvfadd, as1_tn, add1tn, tmp0, ops);
01026 Erase_AddrTN(add1tn);
01027 }
01028 if (flag & 4) {
01029 Build_OP(TOP_c3_mvfadd, as2_tn, add2tn, tmp0, ops);
01030 Erase_AddrTN(add2tn);
01031 }
01032
01033 return result;
01034
01035 }
01036
01037
01038 TN *Expand_C3_INIT_DACC (WN *intrncall, TN *result, OPS *ops) {
01039
01040 Is_True(WN_kid0(intrncall), ("sl1_l_acquire_dual_acc: argument is incomplete"));
01041 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
01042 TN *shl_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01043 TN *kid1_tn = Expand_Expr (WN_kid2(intrncall), intrncall, NULL);
01044 TN *shl1_tn = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01045 INT32 varidx = Get_Resultidx_Intrncall(intrncall);
01046 TN *acc_tn = Create_Var2DualAcc_Map(varidx);
01047 TN *dacc_tn = Get_DualAccTN(acc_tn);
01048
01049 Build_OP(TOP_c3_mvtacc, acc_tn, kid0_tn, shl_tn, ops);
01050 Build_OP(TOP_c3_mvtacc, dacc_tn, kid1_tn, shl1_tn, ops);
01051
01052 return kid0_tn;
01053 }
01054
01055 TN *Expand_C3_SAVE_DACC (WN *intrncall, TN *result, OPS *ops) {
01056
01057 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall), ("sl1_l_free_dual_acc: operand is null"));
01058 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01059
01060 TN *opr_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01061 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
01062 TN *acc_tn = Get_Acc_from_Varidx(varidx);
01063 Is_True(acc_tn, ("sl1_l_free_dual_acc: variable has not acquired acc register"));
01064 TN *dacc_tn = Get_DualAccTN(acc_tn);
01065 TN *tmp1 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01066 TN *tmp2 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01067 TN *tmp0 = Gen_Literal_TN(0,4);
01068
01069 Is_True(TN_has_value(opr_tn), ("sl1_l_free_dual_acc:: the arg 2 must be immediate"));
01070 int oprvalue= TN_value(opr_tn);
01071
01072 if (!result) {
01073 result = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01074 }
01075 if (oprvalue == 1) {
01076 Build_OP(TOP_c3_mvfacc, tmp1, acc_tn, tmp0, ops);
01077 Build_OP(TOP_c3_mvfacc, tmp2, dacc_tn, tmp0, ops);
01078 Build_OP(TOP_c3_saadds, result, tmp1, tmp2, tmp0, ops);
01079 } else if (oprvalue == 0) {
01080
01081
01082 Build_OP(TOP_c3_mvfacc, result, acc_tn, tmp0, ops);
01083 } else {
01084 Is_True(0, ("sl1_l_free_dual_acc: the 2nd argument is unknown immediate"));
01085 }
01086
01087 Erase_Var2DualAcc_Map(varidx);
01088
01089 return result;
01090
01091 }
01092
01093 TN *Expand_C3_DMAC_A (WN *intrncall, TN *result, OPS *ops, BOOL dmac_a = TRUE) {
01094
01095 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall) &&
01096 WN_kid(intrncall, 4) && WN_kid(intrncall, 5) && WN_kid(intrncall, 6)),
01097 ("sl1_l_dmac_p:: argument is incomplete"));
01098
01099 TN *acc_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01100 TN *acmtn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01101 TN *as1_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01102 TN *as1_mode = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01103 TN *as2_tn = Expand_Expr(WN_kid(intrncall, 4), intrncall, NULL);
01104 TN *as2_mode = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);
01105 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6)), 4);
01106 TN *subn_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 7)), 4);
01107 UINT flag= 0;
01108 TN *tmp0 = Gen_Literal_TN(0, 4);
01109 TOP top = dmac_a ? TOP_c3_dmac_a : TOP_c3_dmacn_a;
01110 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
01111 TN *acctn = Get_Acc_from_Varidx(varidx);
01112 INT32 varidx1 = Get_ParmVaridx_Intrncall(intrncall, 2);
01113 TN *add1tn = Get_Addr_from_Varidx(varidx1);
01114 INT32 varidx2 = Get_ParmVaridx_Intrncall(intrncall, 4);
01115 TN *add2tn = Get_Addr_from_Varidx(varidx2);
01116 if (acctn)
01117 Set_Var_AccTN(AccPregN, acctn);
01118
01119 if (!acctn) {
01120 acctn = Get_New_DualAccTN();
01121 Build_OP(TOP_c3_mvtacc, acctn, acc_tn, tmp0, ops);
01122 Build_OP(TOP_c3_mvtacc, Get_DualAccTN(acctn), Zero_TN, tmp0, ops);
01123 flag = 1;
01124 }
01125 if (!add1tn) {
01126 add1tn = Get_New_AddrTN();
01127 Build_OP(TOP_c3_mvtadd, add1tn, as1_tn, tmp0, ops);
01128 flag |=2;
01129 }
01130 if (!add2tn) {
01131 add2tn = Get_New_AddrTN();
01132 Build_OP(TOP_c3_mvtadd, add2tn, as2_tn, tmp0, ops);
01133 flag |=4;
01134 }
01135 Build_OP(top, acctn, Get_DualAccTN(acctn), add1tn, add2tn, acmtn, add1tn, as1_mode, add2tn, as2_mode, subn_tn, bsel_tn, acctn, Get_DualAccTN(acctn), ops);
01136 Set_OP_To_WN_Map(intrncall);
01137 if (flag & 1) {
01138 TN *tmp1 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01139 TN *tmp2 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01140 Build_OP(TOP_c3_mvfacc, tmp1, acctn, tmp0, ops);
01141 Build_OP(TOP_c3_mvfacc, tmp2, Get_DualAccTN(acctn), tmp0, ops);
01142 Build_OP(TOP_c3_saadds, result, tmp1, tmp2, tmp0, ops);
01143 Erase_AccTN(acctn);
01144 Erase_AccTN(Get_DualAccTN(acctn));
01145 }
01146 if (flag & 2) {
01147 Build_OP(TOP_c3_mvfadd, as1_tn, add1tn, tmp0, ops);
01148 Erase_AddrTN(add1tn);
01149 }
01150 if (flag & 4) {
01151 Build_OP(TOP_c3_mvfadd, as2_tn, add2tn, tmp0, ops);
01152 Erase_AddrTN(add2tn);
01153 }
01154
01155 return result;
01156 }
01157
01158
01159
01160
01161
01162
01163
01164 TN *Expand_INIT_ADDR (WN *intrncall, TN *result, OPS *ops) {
01165
01166 Is_True(WN_kid0(intrncall), ("sl1_acquire_addr:: argument is incomplete"));
01167 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
01168 TN *address_mode = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01169
01170 INT32 varidx = Get_Resultidx_Intrncall(intrncall);
01171 TN *addr_tn = Create_Var2Add_Map(varidx);
01172 TN *tmp_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01173
01174 Build_OP(TOP_addiu, tmp_tn, kid0_tn, address_mode, ops);
01175 Build_OP(TOP_c3_mvtadd, addr_tn, tmp_tn, Gen_Literal_TN(0,4), ops);
01176
01177 return kid0_tn;
01178 }
01179
01180 TN *Expand_SAVE_ADDR (WN *intrncall, TN *result, OPS *ops) {
01181
01182 Is_True(WN_kid0(intrncall), ("sl1_free_addr: argument is incomplete"));
01183 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01184 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
01185 TN *addrtn = Get_Addr_from_Varidx(varidx);
01186 Is_True(addrtn, ("sl1_free_addr: variable has not arquired address register"));
01187 if (!result) {
01188 result = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01189 }
01190 Build_OP(TOP_c3_mvfadd, result, addrtn, Gen_Literal_TN(0,4), ops);
01191
01192 Erase_Var2Addr_Map(varidx);
01193
01194 return result;
01195 }
01196
01197
01198
01199 TN *Expand_C3_SAADDH_A (WN *intrncall, TN *result, OPS *ops, BOOL is_add = TRUE) {
01200
01201 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall) &&
01202 WN_kid(intrncall, 4) ),
01203 ("sl1_saaddh_p: arguments are incomplete"));
01204
01205 TN *as1_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01206 TN *as1_mode = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01207 TN *as2_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01208 TN *as2_mode = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01209 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01210 UINT flag= 0;
01211 TN *tmp0 = Gen_Literal_TN(0, 4);
01212 INT32 pregn1 = Get_ParmVaridx_Intrncall(intrncall, 0);
01213 TN *add1tn = Get_Addr_from_Varidx(pregn1);
01214 INT32 pregn2 = Get_ParmVaridx_Intrncall(intrncall, 2);
01215 TN *add2tn = Get_Addr_from_Varidx(pregn2);
01216 TOP top = is_add ? TOP_c3_saaddh_a : TOP_c3_sasubh_a;
01217 if (!add1tn) {
01218 add1tn = Get_New_AddrTN();
01219 Build_OP(TOP_c3_mvtadd, add1tn, as1_tn, tmp0, ops);
01220 flag |=1;
01221 }
01222 if (!add2tn) {
01223 add2tn = Get_New_AddrTN();
01224 Build_OP(TOP_c3_mvtadd, add2tn, as2_tn, tmp0, ops);
01225 flag |=2;
01226 }
01227 Build_OP(top, result, add1tn, add2tn, add1tn, as1_mode, add2tn, as2_mode, bsel_tn, ops);
01228 Set_OP_To_WN_Map(intrncall);
01229 if (flag & 1) {
01230 Build_OP(TOP_c3_mvfadd, as1_tn, add1tn, tmp0, ops);
01231 Erase_AddrTN(add1tn);
01232 }
01233 if (flag & 2) {
01234 Build_OP(TOP_c3_mvfadd, as2_tn, add2tn, tmp0, ops);
01235 Erase_AddrTN(add2tn);
01236 }
01237
01238 return result;
01239 }
01240
01241 TN *Expand_C3_SAMULSH (WN *intrncall, TN *result, OPS *ops) {
01242 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall)),
01243 ("sl1_samulsh:: arguments are incomplete"));
01244
01245 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
01246 TN *kid1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01247 TN *kid2_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01248
01249 Build_OP(TOP_c3_samulsh, result, kid0_tn, kid1_tn, kid2_tn, ops);
01250 return result;
01251 }
01252
01253 TN *Expand_C3_LEAD (WN *intrncall, TN *result, OPS *ops) {
01254
01255 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) ),
01256 ("SL1_c3_lead: arguments are incomplete"));
01257
01258 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
01259 TN *mode = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01260
01261 INT32 pregn1 = Get_ParmVaridx_Intrncall(intrncall, 0);
01262 TN *acctn = Get_Acc_from_Varidx(pregn1);
01263 TN *tmp0 = Gen_Literal_TN(0, 4);
01264 if (acctn) {
01265 Build_OP(TOP_c3_lead, result, acctn, mode, ops);
01266 }
01267 else {
01268 acctn = Get_New_AccTN();
01269 Build_OP(TOP_c3_mvtacc, acctn, kid0_tn, tmp0, ops);
01270 Build_OP(TOP_c3_lead, result, acctn, mode, ops);
01271 Erase_AccTN(acctn);
01272 }
01273 return result;
01274 }
01275
01276 TN *Expand_C3_MULA_A (WN *intrncall, TN *result, OPS *ops) {
01277 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall) &&
01278 WN_kid(intrncall, 4) && WN_kid(intrncall, 5) && WN_kid(intrncall, 6) ),
01279 ("sl1_l_mula_p: arguments are incomplete"));
01280
01281 TN *kidtn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01282 TN *acmtn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01283 TN *as1_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01284 TN *as1_mode = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01285 TN *as2_tn = Expand_Expr(WN_kid(intrncall, 4), intrncall, NULL);
01286 TN *as2_mode = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);
01287 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6)), 4);
01288 TN *shift_num = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 7)), 4);
01289 UINT flag= 0;
01290 TN *tmp0 = Gen_Literal_TN(0, 4);
01291 INT32 pregn1 = Get_ParmVaridx_Intrncall(intrncall, 2);
01292 TN *add1tn = Get_Addr_from_Varidx(pregn1);
01293 INT32 pregn2 = Get_ParmVaridx_Intrncall(intrncall, 4);
01294 TN *add2tn = Get_Addr_from_Varidx(pregn2);
01295 TN *acctn = NULL;
01296 if (TN_has_value(kidtn) || WN_operator(WN_kid0(WN_kid0(intrncall))) == OPR_INTCONST) {
01297 acctn = NULL;
01298 } else {
01299 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
01300 acctn = Get_Acc_from_Varidx(varidx);
01301 }
01302
01303 if (!add1tn) {
01304 add1tn = Get_New_AddrTN();
01305 Build_OP(TOP_c3_mvtadd, add1tn, as1_tn, tmp0, ops);
01306 flag |=1;
01307 }
01308 if (!add2tn) {
01309 add2tn = Get_New_AddrTN();
01310 Build_OP(TOP_c3_mvtadd, add2tn, as2_tn, tmp0, ops);
01311 flag |=2;
01312 }
01313
01314 if (acctn) {
01315 Is_True(TN_value(shift_num) == 0, ("sl1_l_mula_p: shiftnum should be zero"));
01316 Build_OP(TOP_c3_mula_a, acctn, add1tn, add2tn, acmtn, add1tn, as1_mode, add2tn, as2_mode, bsel_tn, ops);
01317 Set_OP_To_WN_Map(intrncall);
01318 } else {
01319 acctn = Get_New_AccTN();
01320 Build_OP(TOP_c3_mula_a, acctn, add1tn, add2tn, acmtn, add1tn, as1_mode, add2tn, as2_mode, bsel_tn, ops);
01321 Set_OP_To_WN_Map(intrncall);
01322 Build_OP(TOP_c3_mvfacc, result, acctn, shift_num, ops);
01323 Erase_AccTN(acctn);
01324 }
01325
01326 if (flag & 1) {
01327 Build_OP(TOP_c3_mvfadd, as1_tn, add1tn, tmp0, ops);
01328 Erase_AddrTN(add1tn);
01329 }
01330 if (flag & 2) {
01331 Build_OP(TOP_c3_mvfadd, as2_tn, add2tn, tmp0, ops);
01332 Erase_AddrTN(add2tn);
01333 }
01334
01335 return result;
01336 }
01337
01338 TN *Expand_C3_SAMULH_A (WN *intrncall, TN *result, OPS *ops) {
01339 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall) &&
01340 WN_kid(intrncall, 4) ), ("sl1_samulh_p: arguments are incomplete"));
01341
01342 TN *as1_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01343 TN *as1_mode = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01344 TN *as2_tn = Expand_Expr(WN_kid(intrncall, 2), intrncall, NULL);
01345 TN *as2_mode = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 3)), 4);
01346 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01347 UINT flag= 0;
01348 TN *tmp0 = Gen_Literal_TN(0, 4);
01349 INT32 pregn1 = Get_ParmVaridx_Intrncall(intrncall, 0);
01350 TN *add1tn = Get_Addr_from_Varidx(pregn1);
01351 INT32 pregn2 = Get_ParmVaridx_Intrncall(intrncall, 2);
01352 TN *add2tn = Get_Addr_from_Varidx(pregn2);
01353
01354 if (!add1tn) {
01355 add1tn = Get_New_AddrTN();
01356 Build_OP(TOP_c3_mvtadd, add1tn, as1_tn, tmp0, ops);
01357 flag |=1;
01358 }
01359 if (!add2tn) {
01360 add2tn = Get_New_AddrTN();
01361 Build_OP(TOP_c3_mvtadd, add2tn, as2_tn, tmp0, ops);
01362 flag |=2;
01363 }
01364
01365 Build_OP(TOP_c3_samulh_a, result, add1tn, add2tn, add1tn, as1_mode, add2tn, as2_mode, bsel_tn, ops);
01366 Set_OP_To_WN_Map(intrncall);
01367 if (flag & 1) {
01368 Build_OP(TOP_c3_mvfadd, as1_tn, add1tn, tmp0, ops);
01369 Erase_AddrTN(add1tn);
01370 }
01371 if (flag & 2) {
01372 Build_OP(TOP_c3_mvfadd, as2_tn, add2tn, tmp0, ops);
01373 Erase_AddrTN(add2tn);
01374 }
01375 return result;
01376 }
01377
01378 TN *Expand_C3_PTR (WN *intrncall, TN *result, OPS *ops) {
01379
01380 INT32 pregn1 = Get_ParmVaridx_Intrncall(intrncall, 1);
01381 TN *add1tn = Get_Addr_from_Varidx(pregn1);
01382 if (add1tn) {
01383 Set_Var_AddrTN(AddPregN, add1tn);
01384 if (dotrace) {
01385 fprintf(TFile, "Expand_C3_PTR :: ");
01386 Print_Addr(add1tn);
01387 }
01388 }
01389 else {
01390 TN *rs1 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01391 Exp_COPY(result, rs1, ops);
01392 }
01393 return result;
01394 }
01395
01396 TN *Expand_C3_MAC_AR (WN *intrncall, TN *result, OPS *ops, BOOL mac_ar = TRUE) {
01397
01398 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) &&
01399 WN_kid3(intrncall) && WN_kid(intrncall, 4) && WN_kid(intrncall, 5)),
01400 ("sl1_l_mac_v_p: arguments are incomplete"));
01401
01402 TN *acc_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01403 TN *acmtn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01404 TN *rs1tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01405 TN *as2_tn = Expand_Expr(WN_kid(intrncall, 3), intrncall, NULL);
01406 TN *as2_mode = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01407 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);
01408 UINT flag= 0;
01409 TN *tmp0 = Gen_Literal_TN(0, 4);
01410 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
01411 TN *acctn = Get_Acc_from_Varidx(varidx);
01412 INT32 varidx2 = Get_ParmVaridx_Intrncall(intrncall, 3);
01413 TN *add2tn = Get_Addr_from_Varidx(varidx2);
01414 TOP top = mac_ar ? TOP_c3_mac_ar : TOP_c3_macn_ar;
01415 if (acctn)
01416 Set_Var_AccTN(AccPregN, acctn);
01417
01418 if (!acctn) {
01419 acctn = Get_New_AccTN();
01420 Build_OP(TOP_c3_mvtacc, acctn, acc_tn, tmp0, ops);
01421 flag = 1;
01422 }
01423 if (!add2tn) {
01424 add2tn = Get_New_AddrTN();
01425 Build_OP(TOP_c3_mvtadd, add2tn, as2_tn, tmp0, ops);
01426 flag |=2;
01427 }
01428
01429 Build_OP(top, acctn, add2tn, acmtn, rs1tn, add2tn, as2_mode, bsel_tn, acctn, ops);
01430 Set_OP_To_WN_Map(intrncall);
01431
01432 if (flag & 1) {
01433 Build_OP(TOP_c3_mvfacc, result, acctn, tmp0, ops);
01434 Erase_AccTN(acctn);
01435 }
01436 if (flag & 2) {
01437 Build_OP(TOP_c3_mvfadd, as2_tn, add2tn, tmp0, ops);
01438 Erase_AddrTN(add2tn);
01439 }
01440 return result;
01441 }
01442
01443
01444 TN *Expand_C3_MULA_AR (WN *intrncall, TN *result, OPS *ops) {
01445 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall) &&
01446 WN_kid(intrncall, 4) && WN_kid(intrncall, 5)),
01447 ("sl1_l_mula_v_p: arguments are incomplete"));
01448 TN *kidtn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01449 TN *acmtn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01450 TN *rs1_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01451 TN *as2_tn = Expand_Expr(WN_kid(intrncall, 3), intrncall, NULL);
01452 TN *as2_mode = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01453 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);
01454 TN *shift_num = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6)), 4);
01455 UINT flag= 0;
01456 TN *tmp0 = Gen_Literal_TN(0, 4);
01457 INT32 pregn2 = Get_ParmVaridx_Intrncall(intrncall, 3);
01458 TN *add2tn = Get_Addr_from_Varidx(pregn2);
01459 TN *acctn = NULL;
01460 if (TN_has_value(kidtn) || WN_operator(WN_kid0(WN_kid0(intrncall))) == OPR_INTCONST) {
01461 acctn = NULL;
01462 } else {
01463 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
01464 acctn = Get_Acc_from_Varidx(varidx);
01465 }
01466 if (!add2tn) {
01467 add2tn = Get_New_AddrTN();
01468 Build_OP(TOP_c3_mvtadd, add2tn, as2_tn, tmp0, ops);
01469 flag =1;
01470 }
01471 if (acctn) {
01472 Is_True(TN_value(shift_num) == 0, ("sl1_l_mula_v_p :: shiftnum should be zero"));
01473 Build_OP(TOP_c3_mula_ar, acctn, add2tn, acmtn, rs1_tn, add2tn, as2_mode, bsel_tn, ops);
01474 Set_OP_To_WN_Map(intrncall);
01475 } else {
01476 acctn = Get_New_AccTN();
01477 Build_OP(TOP_c3_mula_ar, acctn, add2tn, acmtn, rs1_tn, add2tn, as2_mode, bsel_tn, ops);
01478 Set_OP_To_WN_Map(intrncall);
01479 Build_OP(TOP_c3_mvfacc, result, acctn, shift_num, ops);
01480 Erase_AccTN(acctn);
01481 }
01482
01483 if (flag == 1) {
01484 Build_OP(TOP_c3_mvfadd, as2_tn, add2tn, tmp0, ops);
01485 Erase_AddrTN(add2tn);
01486 }
01487
01488 return result;
01489 }
01490
01491 TN *Build_C3_INIT_PTR (WN *intrncall, TN *result, OPS *ops) {
01492 TN *src = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01493 if (!result )
01494 result = Gen_Register_TN(ISA_REGISTER_CLASS_integer, TN_size(src));
01495 Exp_COPY(result, src, ops);
01496
01497 return result;
01498 }
01499
01500 TN *Build_C3_TRBACK(WN *intrncall, TN *result, OPS *ops) {
01501 TN *op1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01502 TN *op2 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01503
01504 Build_OP(TOP_c3_trback, op1, op1, op2, ops);
01505 return op1;
01506 }
01507
01508 TN *Build_C3_VITERBI(WN *intrncall, TN *result, OPS *ops) {
01509 TN *op1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01510 TN *op2 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01511 TN *tmp0 = Gen_Literal_TN(0, 4);
01512
01513 OPS_Append_Op(ops, Fixup_OP(TOP_c3_viterbi, op1));
01514 OPS_Append_Op(ops, Fixup_OP(TOP_c3_viterbi, op1));
01515 OPS_Append_Op(ops, Fixup_OP(TOP_c3_viterbi, op1));
01516 Build_OP(TOP_c3_viterbi, op1, op1, op2, ops);
01517 return op1;
01518 }
01519
01520
01521 TN *Build_C3_FFT(WN *intrncall, TN *result, OPS *ops) {
01522 TN *op1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01523 TN *op2 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01524
01525 Build_OP(TOP_c3_fft, op1, op1, op2, ops);
01526 return op1;
01527 }
01528
01529 TN *Expand_C3_DMULA (WN *intrncall, TN *result, OPS *ops, BOOL isdmula=TRUE) {
01530
01531 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall)),
01532 ("sl1_l_dmula: arguments are incomplete"));
01533 TN *kidtn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
01534 TN *kid0_tn = Expand_Expr (WN_kid1(intrncall), intrncall, NULL);
01535 TN *kid1_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01536 TN *accmode = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01537 TN *shiftnum = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01538
01539 TOP top = isdmula ? TOP_c3_dmula : TOP_c3_dmulan;
01540 TN *acctn = NULL;
01541 if (TN_has_value(kidtn) || WN_operator(WN_kid0(WN_kid0(intrncall))) == OPR_INTCONST) {
01542 acctn = NULL;
01543 } else {
01544 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
01545 acctn = Get_Acc_from_Varidx(varidx);
01546 }
01547 if (acctn) {
01548 Is_True(Get_DualAccTN(acctn), ("sl1_l_dmula: second acc is null"));
01549 Is_True(TN_value(shiftnum) == 0, ("sl1_l_dmula :: shiftnum should be zero"));
01550 Set_Var_AccTN(AccPregN, acctn);
01551 Build_OP(top, acctn, Get_DualAccTN(acctn), accmode, kid0_tn, kid1_tn, ops);
01552 }else {
01553 acctn = Get_New_DualAccTN();
01554 Build_OP(top, acctn, Get_DualAccTN(acctn), accmode, kid0_tn, kid1_tn, ops);
01555
01556
01557 Build_OP(TOP_c3_mvfacc, result, acctn, shiftnum, ops);
01558 Erase_AccTN(acctn);
01559 Erase_AccTN(Get_DualAccTN(acctn));
01560 }
01561 return result;
01562 }
01563
01564 TN *Expand_C3_DMULT_A (WN *intrncall, TN *result, OPS *ops, BOOL dmult_a = TRUE) {
01565
01566 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall) &&
01567 WN_kid(intrncall, 4) && WN_kid(intrncall, 5) && WN_kid(intrncall, 6)),
01568 ("sl1_l_dmult_p: arguments are incomplete"));
01569
01570 TN *acc_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01571 TN *acmtn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01572 TN *as1_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01573 TN *as1_mode = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01574 TN *as2_tn = Expand_Expr(WN_kid(intrncall, 4), intrncall, NULL);
01575 TN *as2_mode = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);
01576 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6)), 4);
01577 TN *shr_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 7)), 4);
01578
01579 UINT flag= 0;
01580 TN *tmp0 = Gen_Literal_TN(0, 4);
01581 TOP top = dmult_a ? TOP_c3_dmula_a : TOP_c3_dmulan_a;
01582 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
01583 TN *acctn = Get_Acc_from_Varidx(varidx);
01584 INT32 varidx1 = Get_ParmVaridx_Intrncall(intrncall, 2);
01585 TN *add1tn = Get_Addr_from_Varidx(varidx1);
01586 INT32 varidx2 = Get_ParmVaridx_Intrncall(intrncall, 4);
01587 TN *add2tn = Get_Addr_from_Varidx(varidx2);
01588 if (acctn) {
01589 Is_True(Get_DualAccTN(acctn), ("sl1_l_dmult_p: second acc is not valid"));
01590 Set_Var_AccTN(AccPregN, acctn);
01591 }
01592 if (!acctn) {
01593 acctn = Get_New_DualAccTN();
01594 Build_OP(TOP_c3_mvtacc, acctn, acc_tn, tmp0, ops);
01595 Build_OP(TOP_c3_mvtacc, Get_DualAccTN(acctn), Zero_TN, tmp0, ops);
01596 flag = 1;
01597 }
01598 if (!add1tn) {
01599 add1tn = Get_New_AddrTN();
01600 Build_OP(TOP_c3_mvtadd, add1tn, as1_tn, tmp0, ops);
01601 flag |=2;
01602 }
01603 if (!add2tn) {
01604 add2tn = Get_New_AddrTN();
01605 Build_OP(TOP_c3_mvtadd, add2tn, as2_tn, tmp0, ops);
01606 flag |=4;
01607 }
01608 Build_OP(top, acctn, Get_DualAccTN(acctn), add1tn, add2tn, acmtn, add1tn, as1_mode, add2tn, as2_mode, bsel_tn, acctn, Get_DualAccTN(acctn), ops);
01609 Set_OP_To_WN_Map(intrncall);
01610
01611 if (flag & 1) {
01612
01613
01614 Build_OP(TOP_c3_mvfacc, result, acctn, shr_tn, ops);
01615 Erase_AccTN(acctn);
01616 Erase_AccTN(Get_DualAccTN(acctn));
01617 }
01618 if (flag & 2) {
01619 Build_OP(TOP_c3_mvfadd, as1_tn, add1tn, tmp0, ops);
01620 Erase_AddrTN(add1tn);
01621 }
01622 if (flag & 4) {
01623 Build_OP(TOP_c3_mvfadd, as2_tn, add2tn, tmp0, ops);
01624 Erase_AddrTN(add2tn);
01625 }
01626
01627 return result;
01628 }
01629
01630 TN *Expand_Set_CircBuf(WN *intrncall, TN *result, OPS *ops) {
01631 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid(intrncall, 3) && WN_kid(intrncall, 4),
01632 ("sl1_set_CircBuf: arguments are incomplete"));
01633
01634 TN *src_begin = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01635 TN *src_end = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01636 TN *circbuf_id = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01637 TN *cbuf_b = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01638 TN *cbuf_e = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01639 TN *value0 = Gen_Literal_TN(0, 4);
01640 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"));
01641
01642 TN *begin_addr = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01643 TN *end_addr = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01644
01645 Expand_Add(begin_addr, Zero_TN, cbuf_b, MTYPE_I4, ops);
01646 Expand_Add(end_addr, Zero_TN, cbuf_e, MTYPE_I4, ops);
01647
01648 Build_OP(TOP_sw, src_begin, begin_addr, value0, ops);
01649 Set_OP_volatile(OPS_last(ops));
01650 Build_OP(TOP_sw, src_end, end_addr, value0, ops);
01651 Set_OP_volatile(OPS_last(ops));
01652 }
01653
01654 TN *Expand_C3_DADD(WN *intrncall, TN *result, OPS *ops, BOOL is_dadd = TRUE) {
01655 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall)),
01656 ("Expand_C3_DADD/DSUB:: operand is null"));
01657
01658 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01659 TN *kid1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01660 TOP top = is_dadd ? TOP_c3_dadd : TOP_c3_dsub;
01661
01662 Build_OP(top, result, kid0_tn, kid1_tn, ops);
01663 return result;
01664 }
01665
01666
01667 TN *Expand_C3_FFTLD(WN *intrncall, TN *result, OPS *ops) {
01668 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) &&
01669 WN_kid3(intrncall),
01670 ("Expand_C3_FFTLD:: operand is null"));
01671 TN *as1_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01672 TN *am1_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01673 TN *dtyp_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01674 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01675 UINT flag = 0;
01676 INT32 varidx1 = Get_ParmVaridx_Intrncall(intrncall, 0);
01677 TN *add1tn = Get_Addr_from_Varidx(varidx1);
01678 TN *tmp0 = Gen_Literal_TN(0, 4);
01679
01680 if (!result) {
01681 result = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01682 }
01683 if (!add1tn) {
01684 add1tn = Get_New_AddrTN();
01685 Build_OP(TOP_c3_mvtadd, add1tn, as1_tn, tmp0, ops);
01686 flag |=1;
01687 }
01688 Build_OP(TOP_c3_fftld, result, add1tn, add1tn, tmp0, am1_tn, dtyp_tn, bsel_tn, ops);
01689 Set_OP_To_WN_Map(intrncall);
01690 if (flag == 1) {
01691 Build_OP(TOP_c3_mvfadd, as1_tn, add1tn, tmp0, ops);
01692 Erase_AddrTN(add1tn);
01693 }
01694 return result;
01695 }
01696
01697
01698 TN *Expand_C3_FFTST(WN *intrncall, TN *result, OPS *ops) {
01699 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) &&
01700 WN_kid3(intrncall) && WN_kid(intrncall, 4),
01701 ("Expand_C3_FFTST:: operand is null"));
01702 TN *rs0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01703 TN *as1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01704 TN *am1_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01705 TN *dtyp_tn = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01706 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01707 UINT flag = 0;
01708 INT32 varidx1 = Get_ParmVaridx_Intrncall(intrncall, 1);
01709 TN *add1tn = Get_Addr_from_Varidx(varidx1);
01710 TN *tmp0 = Gen_Literal_TN(0, 4);
01711
01712 if (!result) {
01713 result = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01714 }
01715 if (!add1tn) {
01716 add1tn = Get_New_AddrTN();
01717 Build_OP(TOP_c3_mvtadd, add1tn, as1_tn, tmp0, ops);
01718 flag |=1;
01719 }
01720 Build_OP(TOP_c3_fftst, add1tn, rs0_tn, add1tn, tmp0, am1_tn, dtyp_tn, bsel_tn, ops);
01721 Set_OP_To_WN_Map(intrncall);
01722 if (flag == 1) {
01723 Build_OP(TOP_c3_mvfadd, as1_tn, add1tn, tmp0, ops);
01724 Erase_AddrTN(add1tn);
01725 }
01726 return result;
01727 }
01728
01729
01730
01731 TN *Expand_Deposit(WN *intrncall, TN *result, OPS *ops) {
01732 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall),
01733 ("Expand_Deposit:: operand is null"));
01734 TN *rs0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01735 TN *rs1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01736 TN *pos_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01737 TN *width_tn = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01738 Exp_COPY(result, rs0_tn, ops);
01739 Build_OP(TOP_depb, result, result, rs1_tn, pos_tn, width_tn, ops);
01740
01741 return result;
01742 }
01743
01744
01745 TN *Expand_Extract(WN *intrncall, TN *result, OPS *ops) {
01746 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall),
01747 ("Expand_Extract:: operand is null"));
01748 TN *rs0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01749 TN *pos_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01750 TN *width_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01751
01752 Is_True(WN_kid0(WN_kid0(intrncall)), ("first actual arg is null"));
01753 TYPE_ID rtype = OPCODE_rtype(WN_opcode(WN_kid0(WN_kid0(intrncall))));
01754 TOP top = (MTYPE_is_signed(rtype)) ? TOP_extrbs : TOP_extrbu;
01755
01756 Build_OP(top, result, rs0_tn, pos_tn, width_tn, ops);
01757
01758 return result;
01759 }
01760
01761
01762 TN *Expand_C3_LD(WN *intrncall, TN *result, OPS *ops) {
01763 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) &&
01764 WN_kid3(intrncall),
01765 ("Expand_C3_LD:: operand is null"));
01766 TN *as1_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01767 TN *am1_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01768 TN *dtyp_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01769 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01770 UINT flag = 0;
01771 INT32 varidx1 = Get_ParmVaridx_Intrncall(intrncall, 0);
01772 TN *add1tn = Get_Addr_from_Varidx(varidx1);
01773 TN *tmp0 = Gen_Literal_TN(0, 4);
01774
01775 if (!result) {
01776 result = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01777 }
01778 if (!add1tn) {
01779 add1tn = Get_New_AddrTN();
01780 Build_OP(TOP_c3_mvtadd, add1tn, as1_tn, tmp0, ops);
01781 flag |=1;
01782 }
01783 Build_OP(TOP_c3_ld, result, add1tn, add1tn, tmp0, am1_tn, dtyp_tn, bsel_tn, ops);
01784 Set_OP_To_WN_Map(intrncall);
01785 if (flag == 1) {
01786 Build_OP(TOP_c3_mvfadd, as1_tn, add1tn, tmp0, ops);
01787 Erase_AddrTN(add1tn);
01788 }
01789 return result;
01790 }
01791
01792
01793 TN *Expand_C3_ST(WN *intrncall, TN *result, OPS *ops) {
01794 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) &&
01795 WN_kid3(intrncall) && WN_kid(intrncall, 4),
01796 ("Expand_C3_ST:: operand is null"));
01797 TN *rs0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01798 TN *as1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01799 TN *am1_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01800 TN *dtyp_tn = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01801 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01802 UINT flag = 0;
01803 INT32 varidx1 = Get_ParmVaridx_Intrncall(intrncall, 1);
01804 TN *add1tn = Get_Addr_from_Varidx(varidx1);
01805 TN *tmp0 = Gen_Literal_TN(0, 4);
01806
01807 if (!result) {
01808 result = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01809 }
01810 if (!add1tn) {
01811 add1tn = Get_New_AddrTN();
01812 Build_OP(TOP_c3_mvtadd, add1tn, as1_tn, tmp0, ops);
01813 flag |=1;
01814 }
01815 Build_OP(TOP_c3_st, add1tn, rs0_tn, add1tn, tmp0, am1_tn, dtyp_tn, bsel_tn, ops);
01816 Set_OP_To_WN_Map(intrncall);
01817 if (flag == 1) {
01818 Build_OP(TOP_c3_mvfadd, as1_tn, add1tn, tmp0, ops);
01819 Erase_AddrTN(add1tn);
01820 }
01821 return result;
01822 }
01823
01824
01825 TN *Expand_C3_DMAC(WN *intrncall, TN *result, OPS *ops, BOOL isdmac=TRUE) {
01826 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall)),
01827 ("sl1_dmac: argument is null"));
01828
01829 TN *kid0_tn = Expand_Expr (WN_kid0(intrncall), intrncall, NULL);
01830 TN *acmode = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01831 TN *kid1_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01832 TN *kid2_tn = Expand_Expr(WN_kid3(intrncall), intrncall, NULL);
01833 TN *n_mode = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01834
01835 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
01836 TN *acctn = Get_Acc_from_Varidx(varidx);
01837 TN *tmp0 = Gen_Literal_TN(0,4);
01838 TN *tmp1 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01839 TN *tmp2 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01840
01841 if (acctn)
01842 Set_Var_AccTN(AccPregN, acctn);
01843
01844 TOP top = isdmac ? TOP_c3_dmac: TOP_c3_dmacn;
01845 if (acctn) {
01846 Build_OP(top, acctn, Get_DualAccTN(acctn), acmode, kid1_tn, kid2_tn, n_mode, acctn, Get_DualAccTN(acctn), ops);
01847 } else {
01848 acctn = Get_New_DualAccTN();
01849 Build_OP(TOP_c3_mvtacc, acctn, kid0_tn, tmp0, ops);
01850 Build_OP(TOP_c3_mvtacc, Get_DualAccTN(acctn), Zero_TN, tmp0, ops);
01851 Build_OP(top, acctn, Get_DualAccTN(acctn), acmode, kid1_tn, kid2_tn, n_mode, acctn, Get_DualAccTN(acctn), ops);
01852 Build_OP(TOP_c3_mvfacc, tmp1, acctn, tmp0, ops);
01853 Build_OP(TOP_c3_mvfacc, tmp2, Get_DualAccTN(acctn), tmp0, ops);
01854 Build_OP(TOP_c3_saadds, result, tmp1, tmp2, tmp0, ops);
01855 Erase_AccTN(acctn);
01856 Erase_AccTN(Get_DualAccTN(acctn));
01857 }
01858 return result;
01859 }
01860
01861
01862 TN *Expand_C3_BITR(WN *intrncall, TN *result, OPS *ops) {
01863 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall)),
01864 ("C3.BITR:: operand is null"));
01865
01866 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01867 TN *imm5_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01868 TN *mode_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01869
01870 Build_OP(TOP_c3_bitr, result, kid0_tn, imm5_tn, mode_tn, ops);
01871 return result;
01872 }
01873
01874 TN *Expand_C3_REVB(WN *intrncall, TN *result, OPS *ops) {
01875 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall)) ,
01876 ("C3.REVB:: operand is null"));
01877
01878 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01879 TN *imm5_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01880
01881 Build_OP(TOP_c3_revb, result, kid0_tn, imm5_tn, ops);
01882 return result;
01883 }
01884
01885
01886 TN *Expand_C3_DSHIFT_I(WN *intrncall, TN *result, OPS *ops, BOOL shl = TRUE) {
01887 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall)) ,
01888 ("C3.shll.i/C3.shrl.i:: operand is null"));
01889
01890 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01891 TN *imm5_hi_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01892 TN *imm5_lo_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01893
01894 TOP top = shl ? TOP_c3_dshll_i : TOP_c3_dshrl_i;
01895 Build_OP(top, result, kid0_tn, imm5_hi_tn, imm5_lo_tn, ops);
01896 return result;
01897 }
01898
01899
01900 TN *Expand_C3_MAC_I(WN *intrncall, TN *result, OPS *ops, BOOL mac_i = TRUE) {
01901 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) &&
01902 WN_kid2(intrncall) && WN_kid(intrncall, 3)) ,
01903 ("C3.mac.i/C3.macn.i:: operand is null"));
01904 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01905 TN *rs1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01906 TN *imm10_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01907 TN *acmode = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01908 TOP top = mac_i ? TOP_c3_mac_i : TOP_c3_macn_i;
01909 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
01910 TN *acctn = Get_Acc_from_Varidx(varidx);
01911
01912
01913 if (acctn)
01914 Set_Var_AccTN(AccPregN, acctn);
01915
01916 if (acctn) {
01917 Build_OP(top, acctn, acmode, rs1_tn, imm10_tn, acctn, ops);
01918 } else {
01919 acctn = Get_New_AccTN();
01920 Build_OP(TOP_c3_mvtacc, acctn, kid0_tn, Gen_Literal_TN(0,4), ops);
01921 Build_OP(top, acctn, acmode, rs1_tn, imm10_tn, acctn, ops);
01922 Build_OP(TOP_c3_mvfacc, result, acctn, Gen_Literal_TN(0,4), ops);
01923 Erase_AccTN(acctn);
01924 }
01925 return result;
01926
01927 }
01928
01929
01930 TN *Expand_C3_MULA_I(WN *intrncall, TN *result, OPS *ops) {
01931
01932 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid(intrncall, 4) &&
01933 WN_kid2(intrncall) && WN_kid(intrncall, 3)) ,
01934 ("C3.mula.i:: operand is null"));
01935
01936 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01937 TN *rs1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
01938 TN *imm10_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
01939 TN *acmode = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01940 TN *shr_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01941 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
01942 TN *acctn = Get_Acc_from_Varidx(varidx);
01943
01944
01945 if (acctn)
01946 Set_Var_AccTN(AccPregN, acctn);
01947
01948 if (acctn) {
01949 Build_OP(TOP_c3_mula_i, acctn, acmode, rs1_tn, imm10_tn, acctn, ops);
01950 } else {
01951 acctn = Get_New_AccTN();
01952 Build_OP(TOP_c3_mvtacc, acctn, kid0_tn, Gen_Literal_TN(0,4), ops);
01953 Build_OP(TOP_c3_mula_i, acctn, acmode, rs1_tn, imm10_tn, ops);
01954 Build_OP(TOP_c3_mvfacc, result, acctn, shr_tn, ops);
01955 Erase_AccTN(acctn);
01956 }
01957 return result;
01958
01959 }
01960
01961
01962 TN *Expand_C3_SAADD_A(WN *intrncall, TN *result, OPS *ops, BOOL is_add = TRUE) {
01963 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall) &&
01964 WN_kid(intrncall, 4)),
01965 ("C3.saadd.a: arguments are incomplete"));
01966
01967 TN *as1_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
01968 TN *as1_mode = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
01969 TN *as2_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
01970 TN *as2_mode = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
01971 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
01972 UINT flag= 0;
01973 TN *tmp0 = Gen_Literal_TN(0, 4);
01974 INT32 pregn1 = Get_ParmVaridx_Intrncall(intrncall, 0);
01975 TN *add1tn = Get_Addr_from_Varidx(pregn1);
01976 INT32 pregn2 = Get_ParmVaridx_Intrncall(intrncall, 2);
01977 TN *add2tn = Get_Addr_from_Varidx(pregn2);
01978 TOP top = is_add ? TOP_c3_saadd_a : TOP_c3_sasub_a;
01979 if (!add1tn) {
01980 add1tn = Get_New_AddrTN();
01981 Build_OP(TOP_c3_mvtadd, add1tn, as1_tn, tmp0, ops);
01982 flag |=1;
01983 }
01984 if (!add2tn) {
01985 add2tn = Get_New_AddrTN();
01986 Build_OP(TOP_c3_mvtadd, add2tn, as2_tn, tmp0, ops);
01987 flag |=2;
01988 }
01989 Build_OP(top, result, add1tn, add2tn, add1tn, as1_mode, add2tn, as2_mode, bsel_tn, ops);
01990 Set_OP_To_WN_Map(intrncall);
01991 if (flag & 1) {
01992 Build_OP(TOP_c3_mvfadd, as1_tn, add1tn, tmp0, ops);
01993 Erase_AddrTN(add1tn);
01994 }
01995 if (flag & 2) {
01996 Build_OP(TOP_c3_mvfadd, as2_tn, add2tn, tmp0, ops);
01997 Erase_AddrTN(add2tn);
01998 }
01999
02000 return result;
02001
02002 }
02003
02004
02005 TN *Expand_C3_SADDHA(WN *intrncall, TN *result, OPS *ops) {
02006 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall) &&
02007 WN_kid(intrncall, 4)),
02008 ("C3.saddha: arguments are incomplete"));
02009
02010 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02011 TN *acm_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02012 TN *rs1_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
02013 TN *imm4_tn = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
02014 TN *n_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
02015
02016 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
02017 TN *acctn = Get_Acc_from_Varidx(varidx);
02018
02019
02020 if (acctn)
02021 Set_Var_AccTN(AccPregN, acctn);
02022
02023 if (acctn) {
02024 Build_OP(TOP_c3_saddha, acctn, acm_tn, rs1_tn, imm4_tn, n_tn, acctn, ops);
02025 } else {
02026 acctn = Get_New_AccTN();
02027 Build_OP(TOP_c3_mvtacc, acctn, kid0_tn, Gen_Literal_TN(0,4), ops);
02028 Build_OP(TOP_c3_saddha, acctn, acm_tn, rs1_tn, imm4_tn, n_tn, acctn, ops);
02029 Build_OP(TOP_c3_mvfacc, result, acctn, Gen_Literal_TN(0,4), ops);
02030 Erase_AccTN(acctn);
02031 }
02032 return result;
02033 }
02034
02035 TN *Expand_C3_SADDHA_A(WN *intrncall, TN *result, OPS *ops) {
02036 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) &&
02037 WN_kid3(intrncall) && WN_kid(intrncall, 4) && WN_kid(intrncall, 5) && WN_kid(intrncall, 6)),
02038 ("c3.saddha.a: arguments are incomplete"));
02039
02040 TN *acc_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02041 TN *acmtn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02042 TN *as1_tn = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
02043 TN *as1_mode = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 3)), 4);
02044 TN *imm4_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);;
02045 TN *n_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);;
02046 TN *bsel_tn = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6)), 4);
02047
02048 UINT flag= 0;
02049 TN *tmp0 = Gen_Literal_TN(0, 4);
02050 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
02051 TN *acctn = Get_Acc_from_Varidx(varidx);
02052 INT32 varidx1 = Get_ParmVaridx_Intrncall(intrncall, 2);
02053 TN *add1tn = Get_Addr_from_Varidx(varidx1);
02054
02055 if (acctn)
02056 Set_Var_AccTN(AccPregN, acctn);
02057
02058 if (!acctn) {
02059 acctn = Get_New_AccTN();
02060 Build_OP(TOP_c3_mvtacc, acctn, acc_tn, tmp0, ops);
02061 flag = 1;
02062 }
02063 if (!add1tn) {
02064 add1tn = Get_New_AddrTN();
02065 Build_OP(TOP_c3_mvtadd, add1tn, as1_tn, tmp0, ops);
02066 flag |=2;
02067 }
02068
02069 Build_OP(TOP_c3_saddha_a, acctn, add1tn, acmtn, add1tn, as1_mode, imm4_tn, n_tn, bsel_tn, acctn, ops);
02070 Set_OP_To_WN_Map(intrncall);
02071
02072 if (flag & 1) {
02073 Build_OP(TOP_c3_mvfacc, result, acctn, tmp0, ops);
02074 Erase_AccTN(acctn);
02075 }
02076 if (flag & 2) {
02077 Build_OP(TOP_c3_mvfadd, as1_tn, add1tn, tmp0, ops);
02078 Erase_AddrTN(add1tn);
02079 }
02080 return result;
02081
02082 }
02083
02084 TN *Expand_COPY_ADDR(WN *intrncall, TN *result, OPS *ops) {
02085 Is_True(WN_kid0(intrncall), ("sl1_copy_addr: argument is incomplete"));
02086
02087 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02088 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
02089 TN *addrtn = Get_Addr_from_Varidx(varidx);
02090 Is_True(addrtn, ("sl1_copy_addr: variable has not arquired address register"));
02091 if (!result) {
02092 result = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
02093 }
02094 Build_OP(TOP_c3_mvfadd, result, addrtn, Gen_Literal_TN(0,4), ops);
02095
02096 return result;
02097
02098 }
02099
02100 TN *Expand_SET_ADDRSIZE (WN *intrncall, TN *result, OPS *ops) {
02101
02102 Is_True(WN_kid0(intrncall), ("sl1_set_addrsize: argument is incomplete"));
02103 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02104 TN *step_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02105
02106 INT32 varidx = Get_ParmVaridx_Intrncall(intrncall);
02107 TN *addrtn = Get_Addr_from_Varidx(varidx);
02108 Is_True(addrtn, ("sl1_size_addrsize: argument 0 has not arquired address register"));
02109 Is_True(TN_value(step_tn), ("sl1_size_addrsize: argument 1 should be larger than 0"));
02110
02111 TN *tmp_tn = Gen_Register_TN (ISA_REGISTER_CLASS_integer, 4);
02112 TN *addrs_tn = Get_AddrSize_Reg(addrtn);
02113 Expand_Add(tmp_tn, Zero_TN, step_tn, MTYPE_I4, ops);
02114 Build_OP(TOP_c3_mvtadds, addrs_tn, addrtn, tmp_tn, Gen_Literal_TN(0,4), addrtn, ops);
02115
02116 return result;
02117 }
02118
02119 TN* Expand_Float64_Const(WN* intrncall, TN* result, BOOL Is_high, OPS *ops)
02120 {
02121
02122
02123
02124
02125
02126
02127 WN* kid0 = WN_kid0(intrncall);
02128 if(!kid0) {
02129 Print_Src_Line(current_srcpos, stderr);
02130 Fail_FmtAssertion("line %d: Parameter is NULL when handling CVT64", SRCPOS_linenum(current_srcpos));
02131 }
02132
02133 WN* const_val = WN_kid0(kid0);
02134
02135 if(WN_operator(const_val) != OPR_CONST) {
02136 Print_Src_Line(current_srcpos, stderr);
02137 Fail_FmtAssertion("line %d: constant expected when handling CVT64", SRCPOS_linenum(current_srcpos));
02138 }
02139
02140 ST* sym = WN_st(const_val);
02141 TCON tcon = STC_val(sym);
02142 INTRINSIC id = WN_intrinsic(intrncall);
02143 INT32 val = (id == INTRN_CVT64_LOW) ? TCON_v0(tcon) : TCON_v1(tcon);
02144 if(val == 0)
02145 Exp_COPY(result, Zero_TN, ops);
02146 else {
02147 Build_OP (TOP_lui, result, Gen_Literal_TN((val >> 16)&0xffff, 4), ops);
02148 Build_OP(TOP_ori, result, result, Gen_Literal_TN(val & 0xffff, 4), ops);
02149 }
02150 return result;
02151 }
02152
02153
02154 TN* Expand_LONGLONG_Const(WN* intrncall, TN* result, BOOL Is_high, OPS *ops)
02155 {
02156
02157
02158
02159
02160
02161
02162 WN* kid0 = WN_kid0(intrncall);
02163 if(!kid0) {
02164 Print_Src_Line(current_srcpos, stderr);
02165 Fail_FmtAssertion("line %d: Parameter is NULL when handling LONLONG CVT64", SRCPOS_linenum(current_srcpos));
02166 }
02167
02168 WN* const_val = WN_kid0(kid0);
02169
02170 if(WN_operator(const_val) != OPR_INTCONST) {
02171 Print_Src_Line(current_srcpos, stderr);
02172 Fail_FmtAssertion("line %d: constant expected when handling CVT64", SRCPOS_linenum(current_srcpos));
02173 }
02174
02175 INTRINSIC id = WN_intrinsic(intrncall);
02176 INT32 val = (id == INTRN_LONGLONG_CVT64_LOW) ? (WN_const_val(const_val) & 0xffffffff) :( (WN_const_val(const_val) >> 32) & 0xffffffff);
02177 if(val == 0)
02178 Exp_COPY(result, Zero_TN, ops);
02179 else {
02180 Build_OP (TOP_lui, result, Gen_Literal_TN((val >> 16)&0xffff, 4), ops);
02181 Build_OP(TOP_ori, result, result, Gen_Literal_TN(val & 0xffff, 4), ops);
02182 }
02183 return result;
02184 }
02185
02186
02187 TN* Expand_Float32_Const(WN* intrncall, TN* result, OPS *ops)
02188 {
02189
02190
02191
02192
02193
02194
02195 WN* kid0 = WN_kid0(intrncall);
02196 if(!kid0) {
02197 Print_Src_Line(current_srcpos, stderr);
02198 Fail_FmtAssertion("line %d: Parameter is NULL when handling CVT64", SRCPOS_linenum(current_srcpos));
02199 }
02200
02201 WN* const_val = WN_kid0(kid0);
02202
02203 if(WN_operator(const_val) != OPR_CONST) {
02204 Print_Src_Line(current_srcpos, stderr);
02205 Fail_FmtAssertion("line %d: constant expected when handling CVT32", SRCPOS_linenum(current_srcpos));
02206 }
02207
02208 ST* sym = WN_st(const_val);
02209 TCON tcon = STC_val(sym);
02210 INTRINSIC id = WN_intrinsic(intrncall);
02211 INT32 val = TCON_v0(tcon);
02212 if(val == 0)
02213 Exp_COPY(result, Zero_TN, ops);
02214 else {
02215 Build_OP (TOP_lui, result, Gen_Literal_TN((val >> 16)&0xffff, 4), ops);
02216 Build_OP(TOP_ori, result, result, Gen_Literal_TN(val & 0xffff, 4), ops);
02217 }
02218 return result;
02219 }
02220
02221
02222 TN *Expand_Unsigned_Extract(WN *intrncall, TN *result, OPS *ops) {
02223 WN *kid0 = WN_kid0(WN_kid0(intrncall));
02224 Is_True(WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall),
02225 ("Expand_Unsigned_Extract:: operand is null"));
02226 TN *rs0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02227 TN *pos_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02228 TN *width_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
02229
02230 Is_True(kid0, ("first actual arg is null"));
02231 if (!(WN_operator(kid0) == OPR_INTCONST || WN_operator(kid0) == OPR_CONST)) {
02232
02233 TYPE_ID rtype = OPCODE_rtype(WN_opcode(kid0));
02234 Is_True(MTYPE_is_unsigned(rtype), ("operand should be unsigned"));
02235 }
02236 Build_OP(TOP_extrbu, result, rs0_tn, pos_tn, width_tn, ops);
02237
02238 return result;
02239 }
02240
02241
02242 TN *Expand_C3_aadda(WN *intrncall, TN *result, OPS *ops) {
02243 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall)),
02244 ("Sl1_aadda:arguments are incomplete"));
02245
02246 TN *accd = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02247 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02248 TN *accs = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
02249 TN *m = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
02250 UINT flag= 0;
02251 TN *tmp0 = Gen_Literal_TN(0, 4);
02252 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
02253 TN *accd_tn = Get_Acc_from_Varidx(v1);
02254 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 2);
02255 TN *accs_tn = Get_Acc_from_Varidx(v2);
02256
02257 if (!accd_tn) {
02258 accd_tn = Get_New_AccTN();
02259 Build_OP(TOP_c3_mvtacc, accd_tn, accd, tmp0, ops);
02260 flag = 1;
02261 } else {
02262 Set_Var_AccTN(AccPregN, accd_tn);
02263 }
02264 if (!accs_tn) {
02265 accs_tn = Get_New_AccTN();
02266 Build_OP(TOP_c3_mvtacc, accs_tn, accs, tmp0, ops);
02267 flag |=2;
02268 }
02269 Build_OP(TOP_C3_aadda, accd_tn, acm, accs_tn, m, accd_tn, ops);
02270
02271 if (flag & 1) {
02272 Build_OP(TOP_c3_mvfacc, result, accd_tn, tmp0, ops);
02273 Erase_AccTN(accd_tn);
02274 }
02275 if (flag & 2) {
02276 Erase_AccTN(accs_tn);
02277 }
02278 return result;
02279 }
02280
02281 TN *Expand_C3_bitr(WN *intrncall, TN *result, OPS *ops) {
02282 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall)),
02283 ("Sl1_C3_bitr: operand is null"));
02284
02285 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02286 TN *uimm5_tn = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02287 TN *mode_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
02288
02289 Build_OP(TOP_C3_bitr, result, kid0_tn, uimm5_tn, mode_tn, ops);
02290 return result;
02291 }
02292
02293 TN *Expand_C3_cs(WN *intrncall, TN *result, OPS *ops) {
02294 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall)),
02295 ("Sl1_C3_CS: operand is null"));
02296
02297 TN *rs0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02298 TN *rs1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
02299 TN *mode_tn = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
02300
02301 Build_OP(TOP_C3_cs, result, HI_TN, rs0_tn, rs1_tn, mode_tn, HI_TN, ops);
02302 return result;
02303 }
02304
02305 TN *Expand_C3_Mode0(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
02306 Is_True((const_parm_nums < 3 ), ("const nums < 3"));
02307
02308 TN *kid0_tn = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02309 TN *kid1_tn = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
02310 TN *uimm5[3];
02311 TN *oper;
02312 INT32 value = -1;
02313 INT i=0;
02314 if (has_oper) {
02315 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, (2+const_parm_nums))), 4);
02316 if (TN_has_value(oper)) {
02317 value = TN_value(oper);
02318 } else {
02319 Is_True(0, ("should be 0 or 1"));
02320 }
02321 }
02322 while (const_parm_nums > 0) {
02323 uimm5[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 2+i)), 4);
02324 const_parm_nums--;
02325 i++;
02326 }
02327 switch (top) {
02328 case TOP_C3_dadd: top = value ==1 ? TOP_C3_dsub : top; break;
02329 case TOP_C3_saadds: top = value == 1 ? TOP_C3_sasubs: top; break;
02330 case TOP_C3_saaddsh: top = value == 1 ? TOP_C3_sasubsh: top; break;
02331 case TOP_C3_samulsh: break;
02332 default: Is_True(0, ("unknown TOP"));
02333 }
02334
02335 switch (i) {
02336 case 0: Build_OP(top, result, kid0_tn, kid1_tn, ops); break;
02337 case 1: Build_OP(top, result, kid0_tn, kid1_tn, uimm5[0], ops); break;
02338 default: Is_True(0, ("now only use 0 or 1 uimm5"));
02339 }
02340 return result;
02341 }
02342
02343
02344
02345 TN *Expand_C3_Mode1(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops) {
02346 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02347 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02348 TN *rs1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
02349 TN *rs2 = Expand_Expr(WN_kid3(intrncall), intrncall, NULL);
02350 TN *const_parm[3];
02351 UINT32 flag = 0;
02352 TN *tmp0 = Gen_Literal_TN(0, 4);
02353 INT32 i = 0;
02354 while(const_parm_nums > 0) {
02355 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+i)), 4);
02356 const_parm_nums--;
02357 i++;
02358 }
02359 Is_True(WN_kid(intrncall, 4+const_parm_nums), ("no oper kid"));
02360 TN *oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+i)), 4);
02361 INT32 value = -1;
02362 if (TN_has_value(oper)) {
02363 value = TN_value(oper);
02364 } else {
02365 Is_True(0, ("should be 0 or 1"));
02366 }
02367
02368 switch (top) {
02369 case TOP_C3_mac: top = value == 1 ? TOP_C3_macn : top; break;
02370 case TOP_C3_mula: top = value == 1 ? TOP_C3_mulan : top; break;
02371 default: Is_True(0, ("unknown TOP"));
02372 }
02373
02374 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
02375 TN *acc_tn = Get_Acc_from_Varidx(v1);
02376
02377 if (!acc_tn) {
02378 acc_tn = Get_New_AccTN();
02379 if (top == TOP_C3_mac || top == TOP_C3_macn)
02380 Build_OP(TOP_c3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
02381 flag = 1;
02382 } else {
02383 Set_Var_AccTN(AccPregN, acc_tn);
02384 }
02385 if ((top == TOP_C3_mula) || (top == TOP_C3_mulan)) {
02386 switch (i) {
02387 case 0: Build_OP(top, acc_tn, acm, rs1, rs2, ops); break;
02388 case 1: Build_OP(top, acc_tn, acm, rs1, rs2, const_parm[0], ops); break;
02389 case 2: Build_OP(top, acc_tn, acm, rs1, rs2, const_parm[0], const_parm[1], ops); break;
02390 case 3: Build_OP(top, acc_tn, acm, rs1, rs2, const_parm[0], const_parm[1], const_parm[2], ops); break;
02391 default: Is_True(0, ("const num should <=3 "));
02392 }
02393 } else {
02394 switch (i) {
02395 case 0: Build_OP(top, acc_tn, acm, rs1, rs2, acc_tn, ops); break;
02396 case 1: Build_OP(top, acc_tn, acm, rs1, rs2, const_parm[0], acc_tn, ops); break;
02397 case 2: Build_OP(top, acc_tn, acm, rs1, rs2, const_parm[0], const_parm[1], acc_tn, ops); break;
02398 case 3: Build_OP(top, acc_tn, acm, rs1, rs2, const_parm[0], const_parm[1], const_parm[2], acc_tn, ops); break;
02399 default: Is_True(0, ("const num should <=3 "));
02400 }
02401 }
02402 if (flag == 1) {
02403 Build_OP(TOP_c3_mvfacc, result, acc_tn, tmp0, ops);
02404 Erase_AccTN(acc_tn);
02405 }
02406
02407 return result;
02408 }
02409
02410
02411 TN *Expand_C3_Mode2(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops) {
02412 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02413 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02414 TN *rs1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
02415 TN *rs2 = Expand_Expr(WN_kid3(intrncall), intrncall, NULL);
02416 TN *const_parm[3];
02417 UINT32 flag = 0;
02418 TN *tmp0 = Gen_Literal_TN(0, 4);
02419 INT32 i = 0;
02420 while(const_parm_nums > 0) {
02421 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+i)), 4);
02422 const_parm_nums--;
02423 i++;
02424 }
02425 Is_True(WN_kid(intrncall, 4+const_parm_nums), ("no oper kid"));
02426 TN *oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+i)), 4);
02427 INT32 value = -1;
02428 if (TN_has_value(oper)) {
02429 value = TN_value(oper);
02430 } else {
02431 Is_True(0, ("should be 0 or 1"));
02432 }
02433
02434 switch (top) {
02435 case TOP_C3_dmac: top = value == 1 ? TOP_C3_dmacn : top; break;
02436 case TOP_C3_dmula: top = value == 1 ? TOP_C3_dmulan : top; break;
02437 default: Is_True(0, ("unkown TOP"));
02438 }
02439
02440 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
02441 TN *acc_tn = Get_Acc_from_Varidx(v1);
02442 TN *acc1_tn;
02443 if (!acc_tn) {
02444 acc_tn = Get_New_DualAccTN();
02445 acc1_tn = Get_DualAccTN(acc_tn);
02446 if (top == TOP_C3_dmac || top == TOP_C3_dmacn) {
02447 Build_OP(TOP_C3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
02448 Build_OP(TOP_C3_mvtacc, acc1_tn, Zero_TN, tmp0, ops);
02449 }
02450 flag = 1;
02451 } else {
02452 Set_Var_AccTN(AccPregN, acc_tn);
02453 acc1_tn = Get_DualAccTN(acc_tn);
02454 }
02455 switch (i) {
02456 case 0: Build_OP(top, acc_tn, acc1_tn, acm, rs1, rs2, acc_tn, acc1_tn, ops); break;
02457 case 1: Build_OP(top, acc_tn, acc1_tn, acm, rs1, rs2, const_parm[0], acc_tn, acc1_tn, ops); break;
02458 case 2: Build_OP(top, acc_tn, acc1_tn, acm, rs1, rs2, const_parm[0], const_parm[1], acc_tn, acc1_tn, ops); break;
02459 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;
02460 default: Is_True(0, ("const num should <=3 "));
02461 }
02462
02463 if (flag == 1) {
02464 TN *tmp1 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
02465 TN *tmp2 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
02466 Build_OP(TOP_C3_mvfacc, tmp1, acc_tn, tmp0, ops);
02467 Build_OP(TOP_C3_mvfacc, tmp2, acc1_tn, tmp0, ops);
02468 Build_OP(TOP_C3_saadds, result, tmp1, tmp2, tmp0, ops);
02469 Erase_AccTN(acc_tn);
02470 Erase_AccTN(acc1_tn);
02471 }
02472
02473 }
02474
02475
02476 TN *Expand_C3_Mode3(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
02477 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02478 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02479 TN *as1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
02480 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
02481 TN *as2 = Expand_Expr(WN_kid(intrncall, 4), intrncall, NULL);
02482 TN *am2 = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);
02483
02484 TN *const_parm[3];
02485 UINT32 flag = 0;
02486 TN *tmp0 = Gen_Literal_TN(0, 4);
02487 INT32 i = 0;
02488 TN *oper;
02489 INT32 value = -1;
02490
02491 if (has_oper) {
02492 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6+const_parm_nums)), 4);
02493 if (TN_has_value(oper)) {
02494 value = TN_value(oper);
02495 } else {
02496 Is_True(0, ("should be 0 or 1"));
02497 }
02498 }
02499 while(const_parm_nums > 0) {
02500 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6+i)), 4);
02501 const_parm_nums--;
02502 i++;
02503 }
02504
02505 switch (top) {
02506 case TOP_C3_mac_a: top = value == 1 ? TOP_C3_macn_a : top; break;
02507 case TOP_C3_mula_a: break;
02508 default: Is_True(0, ("unknown TOP"));
02509 }
02510
02511 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
02512 TN *acc_tn = Get_Acc_from_Varidx(v1);
02513 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 2);
02514 TN *add1_tn = Get_Addr_from_Varidx(v2);
02515 INT32 v3 = Get_ParmVaridx_Intrncall(intrncall, 4);
02516 TN *add2_tn = Get_Addr_from_Varidx(v3);
02517
02518 if (!acc_tn) {
02519 acc_tn = Get_New_AccTN();
02520 if (top != TOP_C3_mula_a)
02521 Build_OP(TOP_C3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
02522 flag = 1;
02523 } else {
02524 Set_Var_AccTN(AccPregN, acc_tn);
02525 }
02526 if (!add1_tn) {
02527 add1_tn = Get_New_AddrTN();
02528 Build_OP(TOP_C3_mvtaddr, add1_tn, as1, tmp0, ops);
02529 flag |= 2;
02530 }
02531 if (!add2_tn) {
02532 add2_tn = Get_New_AddrTN();
02533 Build_OP(TOP_C3_mvtaddr, add2_tn, as2, tmp0, ops);
02534 flag |= 4;
02535 }
02536
02537 if (top == TOP_C3_mula_a) {
02538 switch (i) {
02539 case 0: Build_OP(top, acc_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, ops); break;
02540 case 1: Build_OP(top, acc_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, const_parm[0], ops); break;
02541 default: Is_True(0, ("const num should <=1 "));
02542 }
02543 } else {
02544 switch (i) {
02545 case 0: Build_OP(top, acc_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, acc_tn, ops); break;
02546 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;
02547 default: Is_True(0, ("const num should <=1 "));
02548 }
02549 }
02550
02551 Set_OP_To_WN_Map(intrncall);
02552
02553 if (flag & 1) {
02554 Build_OP(TOP_C3_mvfacc, result, acc_tn, tmp0, ops);
02555 Erase_AccTN(acc_tn);
02556 }
02557 if (flag & 2) {
02558 Build_OP(TOP_C3_mvfaddr, as1, add1_tn, tmp0, ops);
02559 Erase_AddrTN(add1_tn);
02560 }
02561 if (flag & 4) {
02562 Build_OP(TOP_C3_mvfaddr, as2, add2_tn, tmp0, ops);
02563 Erase_AddrTN(add2_tn);
02564 }
02565 return result;
02566
02567 }
02568
02569
02570 TN *Expand_C3_Mode4(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
02571 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02572 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02573 TN *rs1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
02574 TN *as1 = Expand_Expr(WN_kid(intrncall, 3), intrncall, NULL);
02575 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
02576
02577 TN *const_parm[3];
02578 UINT32 flag = 0;
02579 TN *tmp0 = Gen_Literal_TN(0, 4);
02580 INT32 i = 0;
02581 TN *oper;
02582 INT32 value = -1;
02583
02584 if (has_oper) {
02585 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5 + const_parm_nums)), 4);
02586 if (TN_has_value(oper)) {
02587 value = TN_value(oper);
02588 } else {
02589 Is_True(0, ("should be 0 or 1"));
02590 }
02591 }
02592 while(const_parm_nums > 0) {
02593 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5+i)), 4);
02594 const_parm_nums--;
02595 i++;
02596 }
02597
02598 switch (top) {
02599 case TOP_C3_mac_ar: top = value == 1 ? TOP_C3_macn_ar : top; break;
02600 case TOP_C3_mula_ar: break;
02601 default: Is_True(0, ("unknown TOP"));
02602 }
02603
02604 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
02605 TN *acc_tn = Get_Acc_from_Varidx(v1);
02606 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 3);
02607 TN *add1_tn = Get_Addr_from_Varidx(v2);
02608
02609 if (!acc_tn) {
02610 acc_tn = Get_New_AccTN();
02611 if (top != TOP_C3_mula_ar)
02612 Build_OP(TOP_C3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
02613 flag = 1;
02614 } else {
02615 Set_Var_AccTN(AccPregN, acc_tn);
02616 }
02617 if (!add1_tn) {
02618 add1_tn = Get_New_AddrTN();
02619 Build_OP(TOP_C3_mvtaddr, add1_tn, as1, tmp0, ops);
02620 flag |= 2;
02621 }
02622
02623 switch (i) {
02624 case 0:
02625 {
02626 if (top == TOP_C3_mula_ar)
02627 Build_OP(top, acc_tn, add1_tn, acm, rs1, add1_tn, am1, ops);
02628 else
02629 Build_OP(top, acc_tn, add1_tn, acm, rs1, add1_tn, am1, acc_tn, ops);
02630 break;
02631 }
02632 case 1:
02633 {
02634 if (top == TOP_C3_mula_ar)
02635 Build_OP(top, acc_tn, add1_tn, acm, rs1, add1_tn, am1, const_parm[0], ops);
02636 else
02637 Build_OP(top, acc_tn, add1_tn, acm, rs1, add1_tn, am1, const_parm[0], acc_tn, ops);
02638 break;
02639 }
02640 default: Is_True(0, ("const num should <=1 "));
02641 }
02642
02643 Set_OP_To_WN_Map(intrncall);
02644
02645 if (flag & 1) {
02646 Build_OP(TOP_C3_mvfacc, result, acc_tn, tmp0, ops);
02647 Erase_AccTN(acc_tn);
02648 }
02649 if (flag & 2) {
02650 Build_OP(TOP_C3_mvfaddr, as1, add1_tn, tmp0, ops);
02651 Erase_AddrTN(add1_tn);
02652 }
02653 return result;
02654
02655 }
02656
02657
02658 TN *Expand_C3_Mode5(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
02659 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02660 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02661 TN *rs1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
02662
02663 TN *const_parm[4];
02664 UINT32 flag = 0;
02665 TN *tmp0 = Gen_Literal_TN(0, 4);
02666 INT32 i = 0;
02667 TN *oper;
02668 INT32 value = -1;
02669
02670 if (has_oper) {
02671 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 3+const_parm_nums)), 4);
02672 if (TN_has_value(oper)) {
02673 value = TN_value(oper);
02674 } else {
02675 Is_True(0, ("should be 0 or 1"));
02676 }
02677 }
02678 while(const_parm_nums > 0) {
02679 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 3+i)), 4);
02680 const_parm_nums--;
02681 i++;
02682 }
02683
02684 switch (top) {
02685 case TOP_C3_mac_i: top = value == 1 ? TOP_C3_macn_i : top; break;
02686 case TOP_C3_shlata_i: top = value == 1 ? TOP_C3_shrata_i : top; break;
02687 case TOP_C3_mula_i: break;
02688 case TOP_C3_sadda: break;
02689 case TOP_C3_shav: break;
02690
02691 default: Is_True(0, ("unknown TOP"));
02692 }
02693
02694 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
02695 TN *acc_tn = Get_Acc_from_Varidx(v1);
02696
02697 if (!acc_tn) {
02698 acc_tn = Get_New_AccTN();
02699 if (top != TOP_C3_mula_i)
02700 Build_OP(TOP_C3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
02701 flag = 1;
02702 } else {
02703 Set_Var_AccTN(AccPregN, acc_tn);
02704 }
02705
02706 if ((top == TOP_C3_mula_i) || (top == TOP_C3_shlata_i) || (top == TOP_C3_shrata_i)) {
02707
02708 switch (i) {
02709 case 0: Build_OP(top, acc_tn, acm, rs1, ops); break;
02710 case 1: Build_OP(top, acc_tn, acm, rs1, const_parm[0], ops); break;
02711 case 2: Build_OP(top, acc_tn, acm, rs1, const_parm[0], const_parm[1], ops); break;
02712 case 3: Build_OP(top, acc_tn, acm, rs1, const_parm[0], const_parm[1], const_parm[2], ops); break;
02713 case 4: Build_OP(top, acc_tn, acm, rs1, const_parm[0], const_parm[1], const_parm[2], const_parm[3], ops); break;
02714 default: Is_True(0, ("const num should <=4 "));
02715 }
02716 } else {
02717
02718 switch (i) {
02719 case 0: Build_OP(top, acc_tn, acm, rs1, acc_tn, ops); break;
02720 case 1: Build_OP(top, acc_tn, acm, rs1, const_parm[0], acc_tn, ops); break;
02721 case 2: Build_OP(top, acc_tn, acm, rs1, const_parm[0], const_parm[1], acc_tn, ops); break;
02722 case 3: Build_OP(top, acc_tn, acm, rs1, const_parm[0], const_parm[1], const_parm[2], acc_tn, ops); break;
02723 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;
02724 default: Is_True(0, ("const num should <=4 "));
02725 }
02726 }
02727
02728 if (flag & 1) {
02729 Build_OP(TOP_C3_mvfacc, result, acc_tn, tmp0, ops);
02730 Erase_AccTN(acc_tn);
02731 }
02732
02733 return result;
02734 }
02735
02736
02737 TN *Expand_C3_Mode6(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
02738
02739 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02740 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02741 TN *const_parm[3];
02742 UINT32 flag = 0;
02743 TN *tmp0 = Gen_Literal_TN(0, 4);
02744 INT32 i = 0;
02745 TN *oper;
02746 INT32 value = -1;
02747
02748 if (has_oper) {
02749 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 2+const_parm_nums)), 4);
02750 if (TN_has_value(oper)) {
02751 value = TN_value(oper);
02752 } else {
02753 Is_True(0, ("should be 0 or 1"));
02754 }
02755 }
02756
02757 switch (top) {
02758 case TOP_C3_round: break;
02759 case TOP_C3_shla_i: top = value == 1 ? TOP_C3_shra_i : top ; break;
02760 default: Is_True(0, ("unknown TOP"));
02761 }
02762
02763 while(const_parm_nums > 0) {
02764 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 2+i)), 4);
02765 const_parm_nums--;
02766 i++;
02767 }
02768
02769 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
02770 TN *acc_tn = Get_Acc_from_Varidx(v1);
02771
02772 if (!acc_tn) {
02773 acc_tn = Get_New_AccTN();
02774 Build_OP(TOP_C3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
02775 flag = 1;
02776 } else {
02777 Set_Var_AccTN(AccPregN, acc_tn);
02778 }
02779
02780 switch (i) {
02781 case 0: Build_OP(top, acc_tn, acm, acc_tn, ops); break;
02782 case 1: Build_OP(top, acc_tn, acm, const_parm[0], acc_tn, ops); break;
02783 case 2: Build_OP(top, acc_tn, acm, const_parm[0], const_parm[1], acc_tn, ops); break;
02784 case 3: Build_OP(top, acc_tn, acm, const_parm[0], const_parm[1], const_parm[2], acc_tn, ops); break;
02785 default: Is_True(0, ("const num should <=3 "));
02786 }
02787
02788 if (flag & 1) {
02789 Build_OP(TOP_C3_mvfacc, result, acc_tn, tmp0, ops);
02790 Erase_AccTN(acc_tn);
02791 }
02792
02793 }
02794
02795
02796
02797 TN *Expand_C3_Mode7(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
02798
02799 TN *as1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02800 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02801 TN *as2 = Expand_Expr(WN_kid(intrncall, 2), intrncall, NULL);
02802 TN *am2 = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 3)), 4);
02803
02804 TN *const_parm[3];
02805 UINT32 flag = 0;
02806 TN *tmp0 = Gen_Literal_TN(0, 4);
02807 INT32 i = 0;
02808 TN *oper;
02809 INT32 value = -1;
02810
02811 if (has_oper) {
02812 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+const_parm_nums)), 4);
02813 if (TN_has_value(oper)) {
02814 value = TN_value(oper);
02815 } else {
02816 Is_True(0, ("should be 0 or 1"));
02817 }
02818 }
02819 while(const_parm_nums > 0) {
02820 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+i)), 4);
02821 const_parm_nums--;
02822 i++;
02823 }
02824
02825 switch (top) {
02826 case TOP_C3_saadd_a: top = value == 1 ? TOP_C3_sasub_a : top; break;
02827 case TOP_C3_saaddh_a: top = value == 1 ? TOP_C3_sasubh_a : top; break;
02828 case TOP_C3_samulh_a: break;
02829 default: Is_True(0, ("unknown TOP"));
02830 }
02831
02832 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 0);
02833 TN *add1_tn = Get_Addr_from_Varidx(v2);
02834 INT32 v3 = Get_ParmVaridx_Intrncall(intrncall, 2);
02835 TN *add2_tn = Get_Addr_from_Varidx(v3);
02836
02837 if (!add1_tn) {
02838 add1_tn = Get_New_AddrTN();
02839 Build_OP(TOP_C3_mvtaddr, add1_tn, as1, tmp0, ops);
02840 flag |= 1;
02841 }
02842 if (!add2_tn) {
02843 add2_tn = Get_New_AddrTN();
02844 Build_OP(TOP_C3_mvtaddr, add2_tn, as2, tmp0, ops);
02845 flag |= 2;
02846 }
02847
02848 switch (i) {
02849 case 0: Build_OP(top, result, add1_tn, add2_tn, add1_tn, am1, add2_tn, am2, ops); break;
02850 case 1: Build_OP(top, result, add1_tn, add2_tn, add1_tn, am1, add2_tn, am2, const_parm[0], ops); break;
02851 case 2: Build_OP(top, result, add1_tn, add2_tn, add1_tn, am1, add2_tn, am2, const_parm[0], const_parm[1], ops); break;
02852 default: Is_True(0, ("const num should <= 2 "));
02853 }
02854
02855 Set_OP_To_WN_Map(intrncall);
02856
02857 if (flag & 1) {
02858 Build_OP(TOP_C3_mvfaddr, as1, add1_tn, tmp0, ops);
02859 Erase_AddrTN(add1_tn);
02860 }
02861 if (flag & 2) {
02862 Build_OP(TOP_C3_mvfaddr, as2, add2_tn, tmp0, ops);
02863 Erase_AddrTN(add2_tn);
02864 }
02865 return result;
02866
02867 }
02868
02869
02870 TN *Expand_C3_Mode8(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
02871 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02872 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
02873 TN *as1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
02874 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
02875 TN *as2 = Expand_Expr(WN_kid(intrncall, 4), intrncall, NULL);
02876 TN *am2 = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);
02877
02878 TN *const_parm[3];
02879 UINT32 flag = 0;
02880 TN *tmp0 = Gen_Literal_TN(0, 4);
02881 INT32 i = 0;
02882 TN *oper;
02883 INT32 value = -1;
02884
02885 if (has_oper) {
02886 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6+const_parm_nums)), 4);
02887 if (TN_has_value(oper)) {
02888 value = TN_value(oper);
02889 } else {
02890 Is_True(0, ("should be 0 or 1"));
02891 }
02892 }
02893 while(const_parm_nums > 0) {
02894 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6+i)), 4);
02895 const_parm_nums--;
02896 i++;
02897 }
02898
02899 switch (top) {
02900 case TOP_C3_dmac_a: top = value == 1 ? TOP_C3_dmacn_a : top; break;
02901 case TOP_C3_dmula_a: top = value == 1 ? TOP_C3_dmulan_a : top; break;
02902 default: Is_True(0, ("unknown TOP"));
02903 }
02904
02905 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
02906 TN *acc_tn = Get_Acc_from_Varidx(v1);
02907 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 2);
02908 TN *add1_tn = Get_Addr_from_Varidx(v2);
02909 INT32 v3 = Get_ParmVaridx_Intrncall(intrncall, 4);
02910 TN *add2_tn = Get_Addr_from_Varidx(v3);
02911 TN *acc1_tn;
02912
02913 if (!acc_tn) {
02914 acc_tn = Get_New_DualAccTN();
02915 acc1_tn = Get_DualAccTN(acc_tn);
02916 if (top == TOP_C3_dmac_a || top == TOP_C3_dmacn_a) {
02917 Build_OP(TOP_C3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
02918 Build_OP(TOP_C3_mvtacc, acc1_tn, Zero_TN, tmp0, ops);
02919 }
02920 flag = 1;
02921 } else {
02922 Set_Var_AccTN(AccPregN, acc_tn);
02923 acc1_tn = Get_DualAccTN(acc_tn);
02924 }
02925 if (!add1_tn) {
02926 add1_tn = Get_New_AddrTN();
02927 Build_OP(TOP_C3_mvtaddr, add1_tn, as1, tmp0, ops);
02928 flag |= 2;
02929 }
02930 if (!add2_tn) {
02931 add2_tn = Get_New_AddrTN();
02932 Build_OP(TOP_C3_mvtaddr, add2_tn, as2, tmp0, ops);
02933 flag |= 4;
02934 }
02935
02936 if (top == TOP_C3_dmula_a || top == TOP_C3_dmulan_a) {
02937 switch (i) {
02938 case 0: Build_OP(top, acc_tn, acc1_tn, add1_tn, add2_tn, acm, add1_tn, am1, add2_tn, am2, ops); break;
02939 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;
02940 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;
02941 default: Is_True(0, ("const num should <=2 "));
02942 }
02943 } else {
02944 switch (i) {
02945 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;
02946 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;
02947 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;
02948 default: Is_True(0, ("const num should <=2 "));
02949 }
02950 }
02951
02952 Set_OP_To_WN_Map(intrncall);
02953
02954 if (flag & 1) {
02955 TN *tmp1 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
02956 TN *tmp2 = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
02957 Build_OP(TOP_C3_mvfacc, tmp1, acc_tn, tmp0, ops);
02958 Build_OP(TOP_C3_mvfacc, tmp2, acc1_tn, tmp0, ops);
02959 Build_OP(TOP_C3_saadds, result, tmp1, tmp2, tmp0, ops);
02960 Erase_AccTN(acc_tn);
02961 Erase_AccTN(acc1_tn);
02962 }
02963 if (flag & 2) {
02964 Build_OP(TOP_C3_mvfaddr, as1, add1_tn, tmp0, ops);
02965 Erase_AddrTN(add1_tn);
02966 }
02967 if (flag & 4) {
02968 Build_OP(TOP_C3_mvfaddr, as2, add2_tn, tmp0, ops);
02969 Erase_AddrTN(add2_tn);
02970 }
02971 return result;
02972
02973 }
02974
02975
02976 TN *Expand_C3_Mode9(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
02977 TN *rs1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
02978 TN *const_parm[3];
02979 UINT32 flag = 0;
02980 TN *tmp0 = Gen_Literal_TN(0, 4);
02981 INT32 i = 0;
02982 TN *oper;
02983 INT32 value = -1;
02984
02985 if (has_oper) {
02986 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 1+const_parm_nums)), 4);
02987 if (TN_has_value(oper)) {
02988 value = TN_value(oper);
02989 } else {
02990 Is_True(0, ("should be 0 or 1"));
02991 }
02992 }
02993 while(const_parm_nums > 0) {
02994 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 1+i)), 4);
02995 const_parm_nums--;
02996 i++;
02997 }
02998
02999 switch (top) {
03000 case TOP_C3_dshll_i: top = value == 1 ? TOP_C3_dshrl_i : top; break;
03001 case TOP_C3_revb: break;
03002 default: Is_True(0, ("unknown TOP"));
03003 }
03004
03005 switch (i) {
03006 case 0: Build_OP(top, result, rs1, ops);
03007 case 1: Build_OP(top, result, rs1, const_parm[0], ops); break;
03008 case 2: Build_OP(top, result, rs1, const_parm[0], const_parm[1], ops); break;
03009 default: Is_True(0, ("const parm number < 3"));
03010 }
03011
03012 return result;
03013 }
03014
03015
03016 TN *Expand_C3_Mode10(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
03017 TN *as1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
03018 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
03019 TN *dtyp = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
03020
03021 TN *const_parm[3];
03022 UINT32 flag = 0;
03023 TN *tmp0 = Gen_Literal_TN(0, 4);
03024 INT32 i = 0;
03025 TN *oper;
03026 INT32 value = -1;
03027
03028 if (has_oper) {
03029 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 3+const_parm_nums)), 4);
03030 if (TN_has_value(oper)) {
03031 value = TN_value(oper);
03032 } else {
03033 Is_True(0, ("should be 0 or 1"));
03034 }
03035 }
03036 while(const_parm_nums > 0) {
03037 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 3+i)), 4);
03038 const_parm_nums--;
03039 i++;
03040 }
03041
03042 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 0);
03043 TN *add1_tn = Get_Addr_from_Varidx(v2);
03044
03045 if (!add1_tn) {
03046 add1_tn = Get_New_AddrTN();
03047 Build_OP(TOP_C3_mvtaddr, add1_tn, as1, tmp0, ops);
03048 flag |= 1;
03049 }
03050
03051 switch (top) {
03052 case TOP_C3_ld: top = value == 1 ? TOP_C3_fftld : top; break;
03053 default: Is_True(0, ("unknown TOP"));
03054 }
03055
03056 switch (i) {
03057 case 0: Build_OP(top, result, add1_tn, add1_tn, tmp0, am1, dtyp, ops); break;
03058 case 1: Build_OP(top, result, add1_tn, add1_tn, tmp0, am1, dtyp, const_parm[0], ops); break;
03059 default: Is_True(0, ("const num should <=1 "));
03060 }
03061
03062 Set_OP_To_WN_Map(intrncall);
03063
03064 if (flag & 1) {
03065 Build_OP(TOP_C3_mvfaddr, as1, add1_tn, tmp0, ops);
03066 Erase_AddrTN(add1_tn);
03067 }
03068
03069 return result;
03070 }
03071
03072
03073 TN *Expand_C3_Mode11(TOP top, WN *intrncall, TN *result, UINT32 const_parm_nums, OPS *ops, BOOL has_oper = TRUE) {
03074 TN *rs1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
03075 TN *as1 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
03076 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
03077 TN *dtyp = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
03078
03079 TN *const_parm[3];
03080 UINT32 flag = 0;
03081 TN *tmp0 = Gen_Literal_TN(0, 4);
03082 INT32 i = 0;
03083 TN *oper;
03084 INT32 value = -1;
03085
03086 if (has_oper) {
03087 oper = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+const_parm_nums)), 4);
03088 if (TN_has_value(oper)) {
03089 value = TN_value(oper);
03090 } else {
03091 Is_True(0, ("should be 0 or 1"));
03092 }
03093 }
03094 while(const_parm_nums > 0) {
03095 const_parm[i] = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4+i)), 4);
03096 const_parm_nums--;
03097 i++;
03098 }
03099
03100 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 1);
03101 TN *add1_tn = Get_Addr_from_Varidx(v2);
03102
03103 if (!add1_tn) {
03104 add1_tn = Get_New_AddrTN();
03105 Build_OP(TOP_C3_mvtaddr, add1_tn, as1, tmp0, ops);
03106 flag |= 1;
03107 }
03108
03109 switch (top) {
03110 case TOP_C3_st: top = value == 1 ? TOP_C3_fftst : top; break;
03111 default: Is_True(0, ("unknown TOP"));
03112 }
03113
03114 switch (i) {
03115 case 0: Build_OP(top, add1_tn, rs1, add1_tn, tmp0, am1, dtyp, ops); break;
03116 case 1: Build_OP(top, add1_tn, rs1, add1_tn, tmp0, am1, dtyp, const_parm[0], ops); break;
03117 default: Is_True(0, ("const num should <=1 "));
03118 }
03119
03120 Set_OP_To_WN_Map(intrncall);
03121
03122 if (flag & 1) {
03123 Build_OP(TOP_C3_mvfaddr, as1, add1_tn, tmp0, ops);
03124 Erase_AddrTN(add1_tn);
03125 }
03126
03127 return result;
03128 }
03129
03130
03131 TN *Expand_C3_shlafa_i(WN *intrncall, TN *result, OPS *ops) {
03132 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
03133 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
03134 TN *uimm5 = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
03135 TN *oper = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
03136 INT32 value = -1;
03137 UINT32 flag = 0;
03138 TN *tmp0 = Gen_Literal_TN(0, 4);
03139 if (TN_has_value(oper)) {
03140 value = TN_value(oper);
03141 } else {
03142 Is_True(0, ("should have oper"));
03143 }
03144 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
03145 TN *acc_tn = Get_Acc_from_Varidx(v1);
03146
03147 TOP top = value == 1 ? TOP_C3_shrafa_i : TOP_C3_shlafa_i;
03148
03149 if (!acc_tn) {
03150 acc_tn = Get_New_AccTN();
03151 Build_OP(TOP_C3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
03152 flag = 1;
03153 }
03154 Build_OP(top, result, acc_tn, acm, uimm5, ops);
03155
03156 if (flag & 1) {
03157 Erase_AccTN(acc_tn);
03158 }
03159 return result;
03160 }
03161
03162
03163 TN *Expand_C3_FFE(WN *intrncall, TN *result, OPS *ops) {
03164 TN *op1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
03165 TN *op2 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
03166 TN *mode = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
03167 Build_OP(TOP_C3_ffe, op1, op1, op2, mode, ops);
03168 return op1;
03169 }
03170
03171
03172 TN *Expand_C3_lead(WN *intrncall, TN *result, OPS *ops) {
03173 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
03174 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
03175 TN *acc_tn = Get_Acc_from_Varidx(v1);
03176 TN *tmp0 = Gen_Literal_TN(0, 4);
03177 INT32 flag = -1;
03178 if (!acc_tn) {
03179 acc_tn = Get_New_AccTN();
03180 Build_OP(TOP_C3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
03181 flag = 1;
03182 }
03183
03184 Build_OP(TOP_C3_lead, result, acc_tn, ops);
03185
03186 if (flag & 1) {
03187 Erase_AccTN(acc_tn);
03188 }
03189 return result;
03190 }
03191
03192
03193
03194 TN *Expand_C3_revb(WN *intrncall, TN *result, OPS *ops) {
03195 TN *op1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
03196 TN *mode = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
03197 Build_OP(TOP_C3_revb, op1, op1, mode, ops);
03198 return op1;
03199 }
03200
03201
03202 TN *Expand_C3_saadda_a(WN *intrncall, TN *result, OPS *ops) {
03203 TN *acc_kid0 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
03204 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
03205 TN *as1_kid1 = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
03206 TN *am1 = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
03207 TN *uimm4 = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 4)), 4);
03208 TN *mode = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 5)), 4);
03209 TN *n = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 6)), 4);
03210 TN *m = Get_Liternal_TN(WN_kid0(WN_kid(intrncall, 7)), 4);
03211 TN *tmp0 = Gen_Literal_TN(0, 4);
03212 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
03213 TN *acc_tn = Get_Acc_from_Varidx(v1);
03214 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 2);
03215 TN *add1_tn = Get_Addr_from_Varidx(v2);
03216 UINT32 flag = 0;
03217
03218 if (!acc_tn) {
03219 acc_tn = Get_New_AccTN();
03220 Build_OP(TOP_C3_mvtacc, acc_tn, acc_kid0, tmp0, ops);
03221 flag = 1;
03222 } else {
03223 Set_Var_AccTN(AccPregN, acc_tn);
03224 }
03225 if (!add1_tn) {
03226 add1_tn = Get_New_AddrTN();
03227 Build_OP(TOP_C3_mvtaddr, add1_tn, as1_kid1, tmp0, ops);
03228 flag |= 2;
03229 }
03230
03231 Build_OP(TOP_C3_sadda_a, acc_tn, add1_tn, acm, add1_tn, am1, uimm4, mode, n, m, acc_tn, ops);
03232
03233 Set_OP_To_WN_Map(intrncall);
03234
03235 if (flag & 1) {
03236 Build_OP(TOP_C3_mvfacc, result, acc_tn, tmp0, ops);
03237 Erase_AccTN(acc_tn);
03238 }
03239
03240 if (flag & 2) {
03241 Build_OP(TOP_C3_mvfaddr, as1_kid1, add1_tn, tmp0, ops);
03242 Erase_AddrTN(add1_tn);
03243 }
03244 return result;
03245 }
03246
03247
03248 TN *Expand_C3_subc(WN *intrncall, TN *result, OPS *ops) {
03249 TN *op1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
03250 TN *op2 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
03251 TN *tmp0 = Gen_Literal_TN(0, 4);
03252 TN *tmp = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03253
03254 Build_OP(TOP_C3_subc, HI_TN, op1, op1, op2, HI_TN, ops);
03255 Exp_COPY(result, op1, ops);
03256 return result;
03257 }
03258
03259
03260 TN *Expand_C3_nega(WN *intrncall, TN *result, OPS *ops) {
03261 Is_True((WN_kid0(intrncall) && WN_kid1(intrncall) && WN_kid2(intrncall) && WN_kid3(intrncall)),
03262 ("Sl1_nega:arguments are incomplete"));
03263
03264 TN *accd = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
03265 TN *acm = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
03266 TN *accs = Expand_Expr(WN_kid2(intrncall), intrncall, NULL);
03267 TN *m = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
03268
03269 UINT flag= 0;
03270 TN *tmp0 = Gen_Literal_TN(0, 4);
03271 INT32 v1 = Get_ParmVaridx_Intrncall(intrncall);
03272 TN *accd_tn = Get_Acc_from_Varidx(v1);
03273 INT32 v2 = Get_ParmVaridx_Intrncall(intrncall, 2);
03274 TN *accs_tn = Get_Acc_from_Varidx(v2);
03275
03276 if (!accd_tn) {
03277 accd_tn = Get_New_AccTN();
03278 Build_OP(TOP_c3_mvtacc, accd_tn, accd, tmp0, ops);
03279 flag = 1;
03280 } else {
03281 Set_Var_AccTN(AccPregN, accd_tn);
03282 }
03283 if (!accs_tn) {
03284 accs_tn = Get_New_AccTN();
03285 Build_OP(TOP_c3_mvtacc, accs_tn, accs, tmp0, ops);
03286 flag |=2;
03287 }
03288 Build_OP(TOP_C3_nega, accd_tn, acm, accs_tn, m, ops);
03289
03290 if (flag & 1) {
03291 Build_OP(TOP_c3_mvfacc, result, accd_tn, tmp0, ops);
03292 Erase_AccTN(accd_tn);
03293 }
03294 if (flag & 2) {
03295 Erase_AccTN(accs_tn);
03296 }
03297 return result;
03298 }
03299
03300
03301 TN *Expand_C3_mul(TOP top, WN *intrncall, TN *result, OPS *ops) {
03302 TN *op1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
03303 TN *op2 = Expand_Expr(WN_kid1(intrncall), intrncall, NULL);
03304 TN *uimm5 = Get_Liternal_TN(WN_kid0(WN_kid2(intrncall)), 4);
03305 TN *hi = Get_Liternal_TN(WN_kid0(WN_kid3(intrncall)), 4);
03306 INT32 value = -1;
03307 if (TN_has_value(hi)) {
03308 value = TN_value(hi);
03309 } else {
03310 Is_True(0, ("hi_bit should be 0/1"));
03311 }
03312
03313
03314 TN *tmp0 = Gen_Literal_TN(0, 4);
03315 TN *tmp = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03316
03317 Build_OP(top, HI_TN, tmp, op1, op2, uimm5, ops);
03318 if (value == 1)
03319 Build_OP(TOP_C3_mvfs, result, HI_TN, tmp0, ops);
03320 else
03321 Exp_COPY(result, tmp, ops);
03322
03323 return result;
03324 }
03325
03326
03327 TN *Expand_Init_HI(WN *intrncall, TN *result, OPS *ops) {
03328 TN *rs1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
03329 TN *uimm5 = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
03330
03331 TOP top = TOP_C3_mvts;
03332 Build_OP(top, HI_TN, rs1, uimm5, ops);
03333 return HI_TN;
03334
03335 }
03336
03337 TN *Expand_Copy_HI(WN *intrncall, TN *result, OPS *ops) {
03338 TN *rs1 = Expand_Expr(WN_kid0(intrncall), intrncall, NULL);
03339 TN *uimm5 = Get_Liternal_TN(WN_kid0(WN_kid1(intrncall)), 4);
03340 TOP top = TOP_C3_mvfs;
03341 Build_OP(top, result, HI_TN, uimm5, ops);
03342 return result;
03343 }
03344
03345