00001
00002
00003
00004
00005
00006
00007 #include "disp_instr.h"
00008 #include "mempool.h"
00009 #include "defs.h"
00010 #include "cxx_memory.h"
00011 #include "tn.h"
00012 #include "label_util.h"
00013 #include "tag.h"
00014 #include "cg_flags.h"
00015 #include "annotations.h"
00016 #include "whirl2ops.h"
00017 #include <vector>
00018 using std::vector;
00019
00020
00021
00022 #define Min_INT5 -16
00023 #define Max_INT5 15
00024
00025
00026
00027 #define Min_uINT5 0
00028 #define Max_uINT5 31
00029
00030
00031
00032 #define Min_sINT7 -64
00033 #define Max_sINT7 63
00034
00035
00036
00037 #define Min_uINT7 0
00038 #define Max_uINT7 127
00039
00040 extern ST *SP_Sym;
00041
00042 void Replace_Size16_Instr (void);
00043 static void Find_Candicate_OP (OP *op);
00044 static OP *prev_16op =NULL;
00045
00046
00047
00048
00049
00050 inline BOOL
00051 Repl_Size16_Instr::Replaceable_TOP_Imm(TOP top, INT32 imm){
00052
00053 BOOL replaceable = FALSE;
00054 switch(top){
00055
00056 case TOP_sll:
00057 case TOP_srl:
00058 case TOP_sra:
00059 case TOP_ori:
00060 case TOP_xori:
00061 case TOP_andi:
00062 if ((imm >= Min_uINT5) && (imm <= Max_uINT5)) {
00063 replaceable = TRUE;
00064 }
00065 break;
00066
00067 case TOP_lw:
00068 case TOP_sw:
00069 if ((imm >= Min_uINT7) && (imm <= Max_uINT7)) {
00070 replaceable = TRUE;
00071 }
00072 break;
00073 default :
00074 Is_True(FALSE, ("%s has no imm operand",top));
00075
00076 }
00077
00078 if (replaceable)
00079 return TRUE;
00080 else
00081 return FALSE;
00082
00083 }
00084
00085
00086 inline BOOL
00087 Repl_Size16_Instr::Tn_Is_Reloc_TN (TN *tn) {
00088 return (TN_is_constant(tn) && TN_relocs(tn));
00089 }
00090
00091
00092
00093
00094 inline void
00095 Repl_Size16_Instr::Replace_CurOP (OP *newop) {
00096 OP_srcpos (newop) = OP_srcpos(_cur_op);
00097 OP_flags(newop) = OP_flags(_cur_op);
00098 if (OP_has_tag(_cur_op)) {
00099 Set_OP_Tag(newop, Get_OP_Tag(_cur_op));
00100 }
00101 if (OP_code(newop) == TOP_mv16) {
00102 Set_OP_copy (newop);
00103 }
00104 if (Get_WN_From_Memory_OP(_cur_op)) {
00105 Copy_WN_For_Memory_OP(newop, _cur_op);
00106 }
00107 BB_Insert_Op_Before(OP_bb(_cur_op), _cur_op, newop);
00108 OP_Change_To_Noop(_cur_op);
00109 _cur_op = newop;
00110 return;
00111 }
00112
00113
00114
00115
00116
00117
00118 BOOL
00119 Repl_Size16_Instr::Replace_ResEqOper_OP (BOOL either = TRUE) {
00120
00121 TOP newtop;
00122 TOP oldtop = OP_code(_cur_op);
00123
00124 switch (oldtop){
00125 case TOP_addu: newtop = TOP_add16; break;
00126 case TOP_and: newtop = TOP_and16; break;
00127 case TOP_or: newtop = TOP_or16; break;
00128 case TOP_xor: newtop = TOP_xor16; break;
00129 case TOP_nor: newtop = TOP_inv16; break;
00130 case TOP_subu: newtop = TOP_sub16; break;
00131 case TOP_sllv: newtop = TOP_shll16; break;
00132 case TOP_srlv: newtop = TOP_shrl16; break;
00133 case TOP_srav: newtop = TOP_shra16; break;
00134 default:
00135 Is_True(FALSE,("%s is not /result eq some operand/", OP_code(_cur_op)));
00136 }
00137
00138 if (OP_results(_cur_op) > 1 || OP_opnds(_cur_op) > 2) {
00139 return FALSE;
00140 }
00141
00142
00143 TN *rtn = OP_result(_cur_op,0);
00144 TN *op1tn = OP_opnd(_cur_op,0);
00145 TN *op2tn = OP_opnd(_cur_op,1);
00146
00147
00148 if (oldtop == TOP_nor) {
00149 if (tn_registers_identical (rtn, op1tn) && tn_registers_identical(op2tn, Zero_TN)) {
00150 OP_Change_Opcode(_cur_op, newtop);
00151 return TRUE;
00152 } else
00153 return FALSE;
00154 }
00155
00156 if (tn_registers_identical (rtn, op1tn)) {
00157 OP_Change_Opcode(_cur_op, newtop);
00158 return TRUE;
00159 }
00160 else if (either && tn_registers_identical (rtn, op2tn)) {
00161 OP *new_op = Mk_OP(newtop, rtn, op2tn, op1tn);
00162 Replace_CurOP(new_op);
00163 return TRUE;
00164 }
00165
00166 if ( oldtop == TOP_addu || oldtop == TOP_or || oldtop == TOP_subu ) {
00167 if (tn_registers_identical(op2tn, Zero_TN)) {
00168
00169 OP *new_op = Mk_OP (TOP_mv16, rtn, op1tn, op2tn);
00170 Replace_CurOP(new_op);
00171 return TRUE;
00172 }
00173 else if (either && tn_registers_identical(op1tn , Zero_TN)) {
00174
00175 OP *new_op = Mk_OP (TOP_mv16, rtn, op2tn, op1tn);
00176 Replace_CurOP(new_op);
00177 return TRUE;
00178 }
00179
00180 }
00181 return FALSE;
00182 }
00183
00184
00185
00186
00187 BOOL
00188 Repl_Size16_Instr::Replace_ADDI (){
00189 Is_True(OP_code(_cur_op) == TOP_addiu,
00190 ("%s is not add.i \n", OP_code(_cur_op)));
00191
00192 if (OP_results(_cur_op) > 1 || OP_opnds(_cur_op) > 2) {
00193 return FALSE;
00194 }
00195
00196
00197
00198 TN *rtn = OP_result (_cur_op, 0);
00199 TN *op1tn = OP_opnd (_cur_op, 0);
00200 TN *op2tn = OP_opnd (_cur_op, 1);
00201
00202 Is_True (TN_is_constant(op2tn),("function called by wrong phase"));
00203 if(Tn_Is_Reloc_TN (op2tn) || TN_is_label(op2tn) || TN_is_enum(op2tn))
00204 return FALSE;
00205
00206 INT32 op2value ;
00207 if (TN_has_value(op2tn)) {
00208 op2value = TN_value (op2tn);
00209 } else if (TN_is_symbol(op2tn)) {
00210 ST *base_st;
00211 INT64 base_ofst;
00212 ST *st = TN_var(op2tn);
00213 Base_Symbol_And_Offset (st, &base_st, &base_ofst);
00214 if (base_st == SP_Sym ) {
00215 Is_True(tn_registers_identical(op1tn, SP_TN), ("Replace_ADDI:: op1tn is $sp when op2tn is sp related "));
00216 op2value= base_ofst + TN_offset(op2tn);
00217 } else {
00218
00219 return FALSE;
00220 }
00221 }
00222
00223 if (!tn_registers_identical (rtn, op1tn) && !tn_registers_identical(op1tn, Zero_TN) && !(op2value==0))
00224 return FALSE;
00225
00226
00227 if (op2value == 0) {
00228 OP *new_op = Mk_OP(TOP_mv16, rtn, op1tn, Zero_TN);
00229 Replace_CurOP(new_op);
00230 return TRUE;
00231 } else if(tn_registers_identical(op1tn, Zero_TN) && (op2value <= Max_uINT5) && (op2value >= Min_uINT5)) {
00232 OP *new_op = Mk_OP (TOP_mv16_i, rtn, op1tn, op2tn);
00233 Replace_CurOP(new_op);
00234 return TRUE;
00235 } else if (tn_registers_identical(rtn, SP_TN) && tn_registers_identical (rtn, op1tn)
00236 && (op2value <= Max_sINT7) && (op2value >= Min_sINT7)) {
00237 Is_True(((op2value&3) == 0), ("addi.sp : imm must be 4 mulpitly"));
00238 OP_Change_Opcode(_cur_op, TOP_add16_sp);
00239 return TRUE;
00240 } else if (tn_registers_identical(rtn, op1tn) && (op2value <= Max_uINT5) && (op2value >= Min_uINT5)) {
00241 OP_Change_Opcode(_cur_op, TOP_add16_i);
00242 return TRUE;
00243 } else if (tn_registers_identical(rtn, op1tn) && (op2value < Min_uINT5) && (op2value >=-Max_uINT5)) {
00244 TN *tmp = Gen_Literal_TN(-op2value, 4);
00245 OP *new_op = Mk_OP (TOP_sub16_i, rtn, op1tn, tmp);
00246 Replace_CurOP(new_op);
00247 return TRUE;
00248 }
00249 return FALSE;
00250 }
00251
00252
00253 BOOL
00254 Repl_Size16_Instr::Replace_LDU () {
00255 TOP newtop;
00256 TOP oldtop = OP_code(_cur_op);
00257 switch (oldtop) {
00258 case TOP_lbu: newtop = TOP_ldub16_rs; break;
00259 case TOP_lhu: newtop = TOP_lduh16_rs; break;
00260 default:
00261 Is_True(FALSE,("%s is not LDU", OP_code(_cur_op)));
00262 }
00263
00264 TN *op1tn, *offsettn, *basetn;
00265
00266 op1tn = OP_result(_cur_op,0);
00267 basetn = OP_opnd(_cur_op,0);
00268 offsettn = OP_opnd(_cur_op,1);
00269
00270 if (tn_registers_identical(op1tn, basetn) && TN_has_value(offsettn) && (TN_value(offsettn)==0)) {
00271 OP_Change_Opcode(_cur_op, newtop);
00272 return TRUE;
00273 }
00274 return FALSE;
00275 }
00276
00277
00278
00279
00280 static int
00281 Label_Offset (OP *op, LABEL_IDX lab) {
00282 int i=0;
00283 BB *cur_bb = OP_bb(op);
00284 OP *tmp_op;
00285 if (OP_bb(op) == NULL) return (Max_INT5+1);
00286
00287 BB *targ_bb = Get_Label_BB(lab);
00288
00289 i = 0;
00290 cur_bb = OP_bb(op);
00291
00292 for (cur_bb = BB_next(cur_bb); cur_bb; cur_bb = BB_next(cur_bb)) {
00293 if (BB_asm(cur_bb))
00294 return (Max_uINT5+1);
00295 else if (BB_call(cur_bb) || BB_exit(cur_bb) || BB_zdl_prolog(cur_bb)) {
00296 i = i + 4;
00297 } else if ((i > Max_uINT5) || (cur_bb == targ_bb))
00298 return i;
00299 i = i + BB_length(cur_bb);
00300
00301 }
00302
00303 }
00304
00305
00306 BOOL
00307 Repl_Size16_Instr::Replace_BR() {
00308 TOP newtop;
00309 TOP oldtop = OP_code(_cur_op);
00310 switch (oldtop) {
00311 case TOP_beq: newtop= TOP_br16_eqz; break;
00312 case TOP_bne: newtop = TOP_br16_nez; break;
00313 default:
00314 Is_True(FALSE,("%s is not branch", (oldtop)));
00315 }
00316
00317
00318 TN *op1tn = OP_opnd (_cur_op, 0);
00319 TN *op2tn = OP_opnd (_cur_op, 1);
00320 TN *op3tn = OP_opnd (_cur_op, 2);
00321
00322 if (tn_registers_identical(op2tn, Zero_TN)) {
00323 if (TN_is_label(op3tn)) {
00324 LABEL_IDX lab = TN_label(op3tn);
00325 int offset = Label_Offset(_cur_op, lab);
00326 if ((offset <=Max_INT5) && (offset >= Min_uINT5) ) {
00327 OP_Change_Opcode(_cur_op, newtop);
00328 return TRUE;
00329 }
00330
00331 }
00332 }
00333 return FALSE;
00334 }
00335
00336
00337
00338
00339
00340
00341
00342 BOOL
00343 Repl_Size16_Instr::Replace_Restricted_Imm_OP () {
00344
00345 TOP newtop;
00346 TOP oldtop = OP_code(_cur_op);
00347
00348 switch (oldtop){
00349 case TOP_sll: newtop = TOP_shll16_i; break;
00350 case TOP_srl: newtop = TOP_shrl16_i; break;
00351 case TOP_sra: newtop = TOP_shra16_i; break;
00352 case TOP_ori: newtop= TOP_or16_i; break;
00353 case TOP_andi: newtop = TOP_and16_i; break;
00354 case TOP_xori: newtop = TOP_xor16_i; break;
00355 default:
00356 Is_True(FALSE,("%s is not Restricted_Imm", OP_code(_cur_op)));
00357 }
00358
00359 if (OP_results(_cur_op) > 1 || OP_opnds(_cur_op) > 2) {
00360 return FALSE;
00361 }
00362
00363
00364
00365 TN *rtn = OP_result (_cur_op, 0);
00366 TN *op1tn = OP_opnd (_cur_op, 0);
00367 TN *op2tn = OP_opnd (_cur_op, 1);
00368
00369 Is_True (TN_is_constant(op2tn),("function called by wrong phase"));
00370
00371 if( Tn_Is_Reloc_TN (op2tn) )
00372 return FALSE;
00373
00374 INT32 op2value = TN_value (op2tn);
00375
00376
00377 if ( oldtop == TOP_ori ) {
00378 if ( !TN_is_symbol(op2tn) && (op2value== 0) ) {
00379
00380 OP *new_op = Mk_OP (TOP_mv16, rtn, op1tn, Zero_TN);
00381 Replace_CurOP(new_op);
00382 return TRUE;
00383 }
00384 else if ( tn_registers_identical(op1tn , Zero_TN) &&
00385 Replaceable_TOP_Imm( oldtop , op2value)) {
00386
00387 OP *new_op = Mk_OP (TOP_mv16_i, rtn, op1tn, op2tn);
00388 Replace_CurOP(new_op);
00389 return TRUE;
00390 }
00391
00392 }
00393
00394 if (tn_registers_identical (rtn, op1tn) ) {
00395 if (Replaceable_TOP_Imm(oldtop , op2value)) {
00396 OP_Change_Opcode(_cur_op, newtop);
00397 return TRUE;
00398 }
00399
00400 }
00401
00402
00403 return FALSE;
00404 }
00405
00406
00407
00408
00409
00410
00411 BOOL
00412 Repl_Size16_Instr::Replace_LdSt_OP () {
00413
00414 TOP newtop;
00415 TOP oldtop = OP_code(_cur_op);
00416
00417 switch (oldtop){
00418 case TOP_lw: newtop = TOP_pop16; break;
00419 case TOP_sw: newtop = TOP_push16; break;
00420 default:
00421 Is_True(FALSE,("%s is not Special Register", OP_code(_cur_op)));
00422 }
00423
00424 TN *op1tn, *offsettn, *basetn;
00425
00426
00427 if(oldtop == TOP_lw){
00428
00429 op1tn = OP_result(_cur_op,0);
00430 basetn = OP_opnd(_cur_op,0);
00431 offsettn = OP_opnd(_cur_op,1);
00432 }
00433
00434 else{
00435 op1tn = OP_opnd(_cur_op,0);
00436 basetn = OP_opnd(_cur_op,1);
00437 offsettn = OP_opnd(_cur_op,2);
00438 }
00439
00440 Is_True( TN_is_register(op1tn) && TN_is_register(basetn) && TN_is_constant(offsettn),
00441 ("function called by wrong phase") );
00442
00443 if( Tn_Is_Reloc_TN (offsettn) )
00444 return FALSE;
00445
00446 if(tn_registers_identical( basetn, SP_TN) ) {
00447 int offset;
00448
00449 if ( TN_is_symbol(offsettn) ) {
00450 ST *base_st, *st;
00451 INT64 base_ofst;
00452
00453 st = TN_var(offsettn);
00454 Base_Symbol_And_Offset (st, &base_st, &base_ofst);
00455 if (base_st == SP_Sym ) {
00456 offset = base_ofst + TN_offset(offsettn);
00457 } else {
00458 Is_True(0,("load/store to 16-bit, must be sp related"));
00459 }
00460 } else if (TN_has_value(offsettn)){
00461 offset = TN_value (offsettn);
00462 } else {
00463 Is_True(0, ("Replace_LdSt_OP:: offset must be imm or $sp related symbol"));
00464 }
00465
00466
00467 if(Replaceable_TOP_Imm(oldtop , offset)) {
00468 OP_Change_Opcode(_cur_op, newtop);
00469 return TRUE;
00470 }
00471 }
00472
00473
00474 if (1) {
00475 int offset;
00476 if (TN_has_value(offsettn)){
00477 offset = TN_value (offsettn);
00478 } else {
00479 return FALSE;
00480 }
00481 if (offset == 0) {
00482 if (oldtop == TOP_lw) {
00483 OP_Change_Opcode(_cur_op, TOP_ldw16);
00484 } else {
00485 OP_Change_Opcode(_cur_op, TOP_stw16);
00486 }
00487 return TRUE;
00488 }
00489
00490 }
00491
00492 return FALSE;
00493 }
00494
00495
00496
00497
00498 BOOL
00499 Repl_Size16_Instr::Replace_Direct_OP () {
00500
00501 TOP newtop;
00502 switch (OP_code(_cur_op)){
00503 case TOP_mvtc: newtop = TOP_mvtc16; break;
00504 case TOP_mvfc: newtop = TOP_mvfc16; break;
00505 case TOP_jr: newtop = TOP_jr16; break;
00506 case TOP_jalr: newtop = TOP_jr16_lnk; break;
00507 case TOP_ret: newtop = TOP_ret16; break;
00508 case TOP_mc_abs: newtop = TOP_abs16; break;
00509 default:
00510 Is_True(FALSE,("%s is not Directly ", OP_code(_cur_op)));
00511 }
00512 OP_Change_Opcode(_cur_op, newtop);
00513 return TRUE;
00514 }
00515
00516 BOOL
00517 Repl_Size16_Instr::Replace_NOP () {
00518
00519 Is_True(OP_code(_cur_op) == TOP_nop,
00520 ("%s is not NOP\n", OP_code(_cur_op)));
00521
00522
00523 if(OP_16bit_op( prev_16op) && !OP_Paired_op(prev_16op) ) {
00524 OP_Change_Opcode(_cur_op, TOP_nop16);
00525 return TRUE;
00526 }
00527 return FALSE;
00528 }
00529
00530 BOOL
00531 Repl_Size16_Instr::Replace_ABS () {
00532 Is_True(OP_code(_cur_op) == TOP_mc_abs,
00533 ("%s is not mc.zn.lt \n", OP_code(_cur_op)));
00534 TN *op1, *result;
00535 result = OP_result(_cur_op, 0);
00536 op1 = OP_opnd(_cur_op,0);
00537
00538 if (tn_registers_identical(result, op1)) {
00539 OP_Change_Opcode(_cur_op, TOP_abs16);
00540 return TRUE;
00541 }
00542 return FALSE;
00543 }
00544
00545
00546
00547
00548
00549 static void Find_Candicate_OP (OP *op){
00550
00551 Repl_Size16_Instr *candi_instr = CXX_NEW(Repl_Size16_Instr(op), &MEM_local_pool);
00552 BOOL replaced= FALSE;
00553 OP *curop=NULL;
00554 switch(OP_code(op)){
00555 case TOP_mc_abs:
00556 replaced = candi_instr->Replace_ABS();
00557 break;
00558 case TOP_addu:
00559 case TOP_and:
00560 case TOP_or:
00561 case TOP_xor:
00562 case TOP_nor:
00563 replaced = candi_instr->Replace_ResEqOper_OP();
00564 break;
00565 case TOP_subu:
00566 case TOP_sllv:
00567 replaced = candi_instr->Replace_ResEqOper_OP(FALSE);
00568 break;
00569 case TOP_addiu:
00570 replaced = candi_instr->Replace_ADDI();
00571 break;
00572 case TOP_srl:
00573 case TOP_sll:
00574 case TOP_sra:
00575 case TOP_ori:
00576 case TOP_andi:
00577 case TOP_xori:
00578 replaced = candi_instr->Replace_Restricted_Imm_OP();
00579 break;
00580 case TOP_lw:
00581 case TOP_sw:
00582 replaced = candi_instr->Replace_LdSt_OP();
00583 break;
00584 case TOP_jr:
00585 case TOP_jalr:
00586 case TOP_mvtc:
00587 case TOP_mvfc:
00588 case TOP_ret:
00589 replaced = candi_instr->Replace_Direct_OP();
00590 break;
00591
00592 case TOP_lbu:
00593 case TOP_lhu:
00594 replaced = candi_instr->Replace_LDU();
00595 break;
00596 case TOP_beq:
00597 case TOP_bne:
00598 if (CG_Enable_br16)
00599 replaced = candi_instr->Replace_BR();
00600 break;
00601 default:
00602
00603 break;
00604 }
00605
00606 if (replaced) {
00607 Set_OP_16bit_op(candi_instr->Get_OP());
00608 }
00609
00610 }
00611
00612
00613 BOOL Reback_Size32_Instr (OP *op) {
00614 Is_True(OP_16bit_op(op), ("should be 16bit op"));
00615
00616 TOP top32;
00617 switch (OP_code(op)) {
00618 case TOP_abs16: top32 = TOP_mc_abs; break;
00619 case TOP_add16: top32 = TOP_addu; break;
00620 case TOP_add16_i: top32 = TOP_addiu; break;
00621 case TOP_add16_sp: top32 = TOP_addiu; break;
00622 case TOP_and16: top32 = TOP_and; break;
00623 case TOP_and16_i: top32 = TOP_andi; break;
00624 case TOP_ldw16: top32 = TOP_lw; break;
00625 case TOP_ldub16_rs: top32 = TOP_lbu; break;
00626 case TOP_lduh16_rs: top32 = TOP_lhu; break;
00627 case TOP_mv16: top32 = TOP_addu; break;
00628 case TOP_mv16_i: top32 = TOP_addiu; break;
00629 case TOP_inv16: top32 = TOP_nor; break;
00630 case TOP_or16: top32 = TOP_or; break;
00631 case TOP_or16_i: top32 = TOP_ori; break;
00632 case TOP_pop16: top32 = TOP_lw; break;
00633 case TOP_push16: top32 = TOP_sw; break;
00634 case TOP_shll16: top32 = TOP_sllv; break;
00635 case TOP_shll16_i: top32 = TOP_sll; break;
00636 case TOP_shra16: top32 = TOP_srav; break;
00637 case TOP_shra16_i: top32 = TOP_sra; break;
00638 case TOP_shrl16: top32 = TOP_srlv; break;
00639 case TOP_shrl16_i: top32 = TOP_srl; break;
00640 case TOP_stw16: top32 = TOP_sw; break;
00641 case TOP_sub16: top32 = TOP_subu; break;
00642 case TOP_sub16_i: top32 = TOP_addiu; break;
00643 case TOP_xor16: top32 = TOP_xor; break;
00644 case TOP_xor16_i: top32 = TOP_xori; break;
00645 case TOP_br16_eqz: top32 = TOP_beq; break;
00646 case TOP_br16_nez: top32 = TOP_bne; break;
00647 case TOP_jr16:
00648 case TOP_jr16_lnk:
00649 case TOP_ret16:
00650 case TOP_mvfc16:
00651 case TOP_mvtc16:
00652 top32 = TOP_UNDEFINED;
00653 break;
00654 default:
00655 Is_True(0, ("unknown 16bit opcode"));
00656 }
00657 if (top32 != TOP_UNDEFINED) {
00658 if (OP_code(op) == TOP_sub16_i) {
00659 INT32 value = TN_value(OP_opnd(op, 1));
00660 TN *valuetn = Gen_Literal_TN(-value, 4);
00661 Set_OP_opnd(op, 1, valuetn);
00662 }
00663 OP_Change_Opcode(op, top32);
00664 return 1;
00665 }
00666 return 0;
00667 }
00668
00669
00670
00671
00672 void Replace_Size16_Instr (void) {
00673
00674 BB* bb;
00675 OP* op;
00676
00677 MEM_POOL_Push(&MEM_local_pool);
00678
00679
00680 for ( bb = REGION_First_BB; bb != NULL; bb = BB_next (bb) ) {
00681 FOR_ALL_BB_OPs_FWD ( bb, op ) {
00682 Find_Candicate_OP (op);
00683 }
00684 }
00685
00686 MEM_POOL_Pop(&MEM_local_pool);
00687
00688 }
00689
00690
00691 void Replace_Size16_Instr(BB *bb) {
00692 OP* op;
00693 FOR_ALL_BB_OPs_FWD ( bb, op ) {
00694 Find_Candicate_OP (op);
00695 }
00696 }
00697
00698
00699 void Guarantee_Paired_instr16 (void) {
00700 BB* bb;
00701 OP* op;
00702 prev_16op = NULL;
00703 for ( bb = REGION_First_BB; bb != NULL; bb = BB_next (bb) ) {
00704 FOR_ALL_BB_OPs_FWD ( bb, op ) {
00705 if (!op)
00706 break;
00707 if (OP_dummy(op))
00708 continue;
00709 if (!prev_16op && OP_16bit_op(op) && !OP_Paired_op(op) ) {
00710 prev_16op = op;
00711 continue;
00712 }
00713 if (prev_16op && (OP_code(op) == TOP_nop)) {
00714 if (!CG_rep_unpaired16) {
00715 OP_Change_Opcode(op, TOP_nop16);
00716 Set_OP_Paired_op(prev_16op);
00717 Set_OP_Paired_op(op);
00718 prev_16op = NULL;
00719 } else {
00720
00721 if (!Reback_Size32_Instr(prev_16op)) {
00722 OP_Change_Opcode(op, TOP_nop16);
00723 Set_OP_Paired_op(prev_16op);
00724 Set_OP_Paired_op(op);
00725 }
00726 prev_16op = NULL;
00727 }
00728 continue;
00729 }
00730 if (prev_16op && OP_16bit_op(op)) {
00731 Set_OP_Paired_op(prev_16op);
00732 Set_OP_Paired_op(op);
00733 prev_16op = NULL;
00734 continue;
00735 }
00736 if (prev_16op && !OP_16bit_op(op)) {
00737 if (!CG_rep_unpaired16) {
00738
00739 OP* nop16 = Mk_OP(TOP_nop16);
00740 BB_Insert_Op_After ( bb, prev_16op, nop16);
00741 Set_OP_Paired_op(prev_16op);
00742 Set_OP_Paired_op(nop16);
00743 prev_16op = NULL;
00744 } else {
00745
00746 if (!Reback_Size32_Instr(prev_16op)) {
00747 OP* nop16 = Mk_OP(TOP_nop16);
00748 BB_Insert_Op_After ( bb, prev_16op, nop16);
00749 Set_OP_Paired_op(prev_16op);
00750 Set_OP_Paired_op(nop16);
00751 }
00752 prev_16op = NULL;
00753 }
00754 continue;
00755 }
00756 }
00757
00758 if (prev_16op && !OP_Paired_op(prev_16op) ) {
00759 if (!CG_rep_unpaired16) {
00760 OP* nop16 = Mk_OP(TOP_nop16);
00761 if (OP_br(prev_16op) || OP_xfer(prev_16op)) {
00762 BB_Insert_Op_Before( bb, prev_16op, nop16);
00763 } else {
00764 BB_Insert_Op_After( bb, prev_16op, nop16);
00765 }
00766 Set_OP_Paired_op(prev_16op);
00767 Set_OP_Paired_op(nop16);
00768 prev_16op = NULL;
00769 } else {
00770
00771 if (!Reback_Size32_Instr(prev_16op)) {
00772 OP* nop16 = Mk_OP(TOP_nop16);
00773 if (OP_br(prev_16op) || OP_xfer(prev_16op)) {
00774 BB_Insert_Op_Before(bb, prev_16op, nop16);
00775 } else {
00776 BB_Insert_Op_After( bb, prev_16op, nop16);
00777 }
00778 Set_OP_Paired_op(prev_16op);
00779 Set_OP_Paired_op(nop16);
00780 }
00781 prev_16op = NULL;
00782 }
00783 }
00784 }
00785
00786 }
00787
00788
00789 UINT32 Control_Register_Index( TN *tn) {
00790 INT idx = -1;
00791 if (tn == RA_TN)
00792 idx = 4;
00793 else if (tn == JA_TN)
00794 idx = 5;
00795 else if (tn == LC0_TN)
00796 idx = 0;
00797 else if (tn == LC1_TN)
00798 idx = 1;
00799 else if (tn == LC2_TN)
00800 idx = 2;
00801 else if (tn == LC3_TN)
00802 idx = 3;
00803 else {
00804 Is_True(0, ("Not a control register"));
00805 }
00806 return idx;
00807 }
00808
00809
00810
00811
00812 void Check_QuadWord_Boundary_Absolute(void) {
00813 BB *bb= NULL;
00814 OP* op= NULL;
00815 UINT32 pc = 0;
00816
00817 MEM_POOL_Push(&MEM_local_pool);
00818 vector<MVTCInfor *> *mvtcop = CXX_NEW(vector<MVTCInfor *>, &MEM_local_pool);
00819 vector<MVTCInfor *> *mvfcop = CXX_NEW(vector<MVTCInfor *>, &MEM_local_pool);
00820
00821 for ( bb = REGION_First_BB; bb != NULL; bb = BB_next (bb) ) {
00822 FOR_ALL_BB_OPs_FWD ( bb, op ) {
00823
00824 if (TOP_is_mvtc(OP_code(op))) {
00825 MVTCInfor *mvtcinfor = CXX_NEW((MVTCInfor), &MEM_local_pool) ;
00826 UINT32 control_register_idx = Control_Register_Index(OP_result(op, 0));
00827 mvtcinfor->cr_idx = control_register_idx;
00828 mvtcinfor->pc = pc;
00829 mvtcop->insert(mvtcop->begin(), mvtcinfor);
00830 } else if ( TOP_is_use_ctrl_reg(OP_code(op))) {
00831 if (mvtcop->size() > 0) {
00832 int cr_idx = -1;
00833 if (OP_code(op ) == TOP_loop) {
00834 cr_idx = Control_Register_Index(OP_opnd(op, 2));
00835 } else {
00836 cr_idx = Control_Register_Index(OP_opnd(op, 0));
00837 }
00838
00839 vector<MVTCInfor *>::iterator temp;
00840 for (temp = mvtcop->begin(); temp != mvtcop->end(); temp++) {
00841 if ((*temp)->cr_idx == cr_idx) {
00842 BB *cur_bb = OP_bb(op);
00843 INT num =(pc - ((*temp)->pc));
00844 if (((16-num)%4)==0)
00845 num = ((16-num)/4);
00846 else
00847 num = ((16-num)/4)+1;
00848 if (num < 0) {
00849 mvtcop->erase(temp);
00850 break;
00851 }
00852 Is_True( (num >=0 && num <=4), ("nop num is between 0-3"));
00853 {
00854 for (int j =0; j< num ; j++) {
00855 OP *op1 = Mk_OP(TOP_nop);
00856 BB_Insert_Op_Before(cur_bb, op, op1);
00857 pc = pc + 4;
00858 }
00859 }
00860
00861 mvtcop->erase(temp);
00862 break;
00863 }
00864 }
00865 }
00866 }
00867 if ((OP_code(op) == TOP_mvfc16) && (Control_Register_Index(OP_opnd(op, 0)) == 4)) {
00868 MVTCInfor *mvfcinfor = CXX_NEW((MVTCInfor), &MEM_local_pool) ;
00869 mvfcinfor->cr_idx = 4;
00870 mvfcinfor->pc = pc;
00871 mvfcop->insert(mvfcop->begin(), mvfcinfor);
00872 } else if ((mvfcop->size() > 0) && TOP_is_lnk(OP_code(op))) {
00873 vector<MVTCInfor *>::iterator temp;
00874 for (temp = mvfcop->begin(); temp != mvfcop->end(); temp++) {
00875 BB *cur_bb = OP_bb(op);
00876 INT num =(pc - ((*temp)->pc));
00877 if (((16-num)%4)==0)
00878 num = ((16-num)/4);
00879 else
00880 num = ((16-num)/4)+1;
00881 if (num < 0) {
00882 mvfcop->erase(temp);
00883 break;
00884 }
00885 Is_True( (num >=0 && num <=4), ("nop num is between 0-3"));
00886 {
00887 for (int j =0; j< num ; j++) {
00888 OP *op1 = Mk_OP(TOP_nop);
00889 BB_Insert_Op_Before(cur_bb, op, op1);
00890 pc = pc + 4;
00891 }
00892 }
00893 mvfcop->erase(temp);
00894 break;
00895 }
00896 }
00897 INT num_inst_words = OP_Real_Inst_Words (op);
00898 pc = pc + (2*num_inst_words);
00899 }
00900 }
00901 MEM_POOL_Pop(&MEM_local_pool);
00902 }
00903
00904
00905 inline OP*
00906 BB_last_real_op(BB *bb) {
00907 OP *last_op;
00908 for (last_op = BB_last_op(bb); last_op; last_op = OP_prev(last_op)) {
00909 if (!OP_dummy(last_op)) break;
00910 }
00911 return last_op;
00912 }
00913
00914 inline OP*
00915 OP_prev_real_op(OP *op) {
00916 OP *prev_op;
00917 for (prev_op = OP_prev(op); prev_op; prev_op = OP_prev(prev_op)) {
00918 if (!OP_dummy(prev_op)) break;
00919 }
00920 return prev_op;
00921 }
00922
00923 void Check_Br16 (int first=0) {
00924 BB *bb= NULL;
00925 OP* op= NULL;
00926 for ( bb = REGION_First_BB; bb != NULL; bb = BB_next (bb) ) {
00927 op = BB_last_real_op(bb);
00928 if (!op )
00929 continue;
00930 if (OP_code(op) == TOP_br16_eqz || OP_code(op) == TOP_br16_nez) {
00931 TN *op1tn = OP_opnd (op, 0);
00932 TN *op2tn = OP_opnd (op, 1);
00933 TN *op3tn = OP_opnd (op, 2);
00934 Is_True(tn_registers_identical(op2tn, Zero_TN), ("second operand is zero"));
00935 if (TN_is_label(op3tn)) {
00936 LABEL_IDX lab = TN_label(op3tn);
00937 int offset = Label_Offset(op, lab);
00938 int upbound = first == 1 ? Max_uINT5 :Max_INT5 ;
00939 if (offset > upbound) {
00940 TOP newtop = (OP_code(op)==TOP_br16_eqz) ? TOP_beq : TOP_bne ;
00941 OP_Change_Opcode(op, newtop);
00942 OP *prev16 = OP_prev_real_op(op);
00943
00944 if (OP_code(prev16) == TOP_nop16) {
00945 OP_Change_To_Noop(prev16);
00946 } else if (OP_16bit_op(prev16)) {
00947 BB_Insert_Op_Before(op->bb, op, Mk_OP(TOP_nop16));
00948 }
00949 }
00950 }
00951 }
00952 }
00953
00954 }
00955
00956
00957
00958