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