00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #define __STDC_LIMIT_MACROS
00063 #include <stdint.h>
00064 #include "defs.h"
00065 #include "config.h"
00066 #include "erglob.h"
00067 #include "ercg.h"
00068 #include "glob.h"
00069 #include "tracing.h"
00070 #include "util.h"
00071
00072 #include "tn.h"
00073 #include "cg_flags.h"
00074 #include "bb.h"
00075 #include "symtab.h"
00076 #include "opcode.h"
00077 #include "const.h"
00078 #include "targ_const.h"
00079 #include "op.h"
00080 #include "data_layout.h"
00081 #include "stblock.h"
00082 #include "cgexp.h"
00083 #include "cgexp_internals.h"
00084 #include "w2op.h"
00085 #include "label_util.h"
00086 #include "cgtarget.h"
00087 #include "whirl2ops.h"
00088 #include "targ_sim.h"
00089
00090
00091 #include <iostream>
00092 #include <vector>
00093 #include <stdlib.h>
00094 #include <strings.h>
00095 #include <map>
00096 #include <fstream>
00097 #include <string>
00098 #include <ctype.h>
00099 #include "glob.h"
00100 #include "lib_phase_dir.h"
00101
00102 BOOL Reuse_Temp_TNs = FALSE;
00103
00104 BOOL Trace_Exp2 = FALSE;
00105
00106
00107 static BOOL Disable_Const_Mult_Opt = FALSE;
00108
00109
00110
00111
00112
00113
00114
00115
00116 #define DUP_TN(tn) Dup_TN_Even_If_Dedicated(tn)
00117
00118 void
00119 Expand_Copy (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
00120 {
00121 if (MTYPE_is_float(mtype))
00122 Build_OP (MTYPE_is_size_double(mtype)?TOP_mov_d: TOP_mov_s,
00123 result, src, ops);
00124 else
00125 Build_OP(TOP_or, result, src, Zero_TN, ops);
00126 Set_OP_copy (OPS_last(ops));
00127 }
00128
00129
00130
00131
00132 static void
00133 Fixup_32_Bit_Op(TN *result,TN *src, TYPE_ID dest_type, OPS *ops)
00134 {
00135 if (dest_type == MTYPE_I8 || dest_type == MTYPE_U8) {
00136 Expand_Copy(result,src,dest_type,ops);
00137 } else {
00138 Expand_Convert_Length (result, src, Gen_Literal_TN(MTYPE_size_reg(dest_type), 4),
00139 dest_type, MTYPE_is_signed(dest_type),ops);
00140 }
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 void
00156 Expand_Convert_Length ( TN *dest, TN *src, TN *length_tn, TYPE_ID mtype, BOOL signed_extension, OPS *ops)
00157 {
00158 TN *lit_tn;
00159 FmtAssert (! MTYPE_float(mtype), ("Expand_Convert_Length: illegal data type\n"));
00160 FmtAssert (TN_has_value(length_tn), ("Expand_Convert_Length: non-constant length\n"));
00161 UINT64 val = TN_value(length_tn);
00162 if (val <= 16 && ! signed_extension)
00163 Build_OP(TOP_andi, dest, src, Gen_Literal_TN((1 << val) - 1, 4), ops);
00164 else if (MTYPE_is_size_double(mtype) || val == 32) {
00165 if (val > 32) {
00166 TN *tmp = Build_TN_Of_Mtype(mtype);
00167 lit_tn = Gen_Literal_TN(64 - val, 4);
00168 Build_OP(TOP_dsll, tmp, src, lit_tn, ops);
00169 Build_OP(signed_extension ? TOP_dsra : TOP_dsrl, dest, tmp, lit_tn, ops);
00170 }
00171 else {
00172 if(Pointer_Size==8) {
00173 TN *tmp = Build_TN_Of_Mtype(mtype);
00174 lit_tn = Gen_Literal_TN(32 - val, 4);
00175 Build_OP(TOP_dsll32, tmp, src, lit_tn, ops);
00176 Build_OP(signed_extension ? TOP_dsra32 : TOP_dsrl32, dest, tmp, lit_tn, ops);
00177 }
00178 else{
00179
00180
00181
00182 Exp_COPY(dest,src,ops);
00183 }
00184 }
00185 }
00186 else {
00187 TN *tmp = Build_TN_Of_Mtype(mtype);
00188 lit_tn = Gen_Literal_TN(32 - val, 4);
00189 Build_OP(TOP_sll, tmp, src, lit_tn, ops);
00190 Build_OP(signed_extension ? TOP_sra : TOP_srl, dest, tmp, lit_tn, ops);
00191 }
00192
00193 }
00194
00195 static void
00196 Exp_Immediate (TN *dest, TN *src, OPS *ops)
00197 {
00198 INT64 val;
00199 TN *tmp = Build_TN_Like(dest);
00200
00201
00202 if ( TN_has_value(src) ) {
00203 val = TN_value(src);
00204 }
00205 else if ( TN_is_symbol(src) ) {
00206 ST *base;
00207 Base_Symbol_And_Offset_For_Addressing (TN_var(src), TN_offset(src), &base,
00208 &val);
00209 }
00210 else FmtAssert(FALSE,("unexpected constant in Exp_Immediate"));
00211
00212 if (TN_is_symbol(src) && TN_relocs(src) == TN_RELOC_GPSUB) {
00213 Build_OP(TOP_lui, tmp,
00214 Gen_Symbol_TN(TN_var(src), 0, TN_RELOC_HI_GPSUB), ops);
00215 Build_OP(TOP_addiu, dest, tmp, Gen_Symbol_TN(TN_var(src), 0,
00216 TN_RELOC_LO_GPSUB), ops);
00217 }
00218 else if (ISA_LC_Value_In_Class (val, LC_simm16)) {
00219 Build_OP (TOP_addiu, dest, Zero_TN, src, ops);
00220 }
00221 else if (ISA_LC_Value_In_Class (val, LC_uimm16)) {
00222 Build_OP (TOP_ori, dest, Zero_TN, src, ops);
00223 }
00224 else if (val >= INT32_MIN && val <= INT32_MAX){
00225 Build_OP (TOP_lui, tmp, Gen_Literal_TN((val >> 16)&0xffff, 4), ops);
00226 Build_OP (TOP_ori, dest, tmp, Gen_Literal_TN(val & 0xffff, 4), ops);
00227 }
00228 else if ((UINT64)val <= UINT32_MAX) {
00229 if (TN_size(dest) == 4)
00230 Build_OP (TOP_lui, tmp, Gen_Literal_TN((val >> 16) & 0xffff, 4), ops);
00231 else {
00232 Build_OP (TOP_ori, tmp, Zero_TN,
00233 Gen_Literal_TN((val >> 16) & 0xffff, 4), ops);
00234 Build_OP (TOP_dsll, tmp, tmp, Gen_Literal_TN(16, 4), ops);
00235 }
00236 Build_OP (TOP_ori, dest, tmp, Gen_Literal_TN(val & 0xffff, 4), ops);
00237 }
00238 else {
00239 TCON tcon = Host_To_Targ (MTYPE_I8, val);
00240 ST *sym = New_Const_Sym (Enter_tcon (tcon), Be_Type_Tbl(MTYPE_I8));
00241 Allocate_Object(sym);
00242 #if 0 // SC temp ifdef out for now to make kvm compile throug
00243 FmtAssert((ST_gprel(sym)), ("sym not gp_rel: handle this"));
00244 #endif
00245 if(ST_gprel(sym)) {
00246
00247 Build_OP(TOP_lw, dest, GP_TN, Gen_Symbol_TN(sym, 0, TN_RELOC_GPREL16), ops);
00248 DevWarn("Long Long value is not supported, constant value has been truncated");
00249 }
00250 else {
00251 TN *tmp1= Build_TN_Like(dest);
00252 Build_OP (TOP_lui, tmp1, Gen_Literal_TN((val & 0xffffffff)>> 16, 8), ops);
00253 Build_OP (TOP_ori, tmp1, tmp1, Gen_Literal_TN(val & 0xffff, 8), ops);
00254
00255
00256
00257 Build_OP (TOP_lui, tmp, Gen_Literal_TN((val >> 48) & 0xffff, 8), ops);
00258 Build_OP (TOP_ori, dest, tmp, Gen_Literal_TN((val >> 32) & 0xffff, 8), ops);
00259
00260 Build_OP (TOP_dsll32, dest, dest, Gen_Literal_TN(0, 8), ops);
00261 Build_OP (TOP_daddu, dest, tmp1, dest, ops);
00262
00263 DevWarn("Long Long value is not supported, constant value has been truncated");
00264 }
00265 }
00266 }
00267
00268 void
00269 Exp_Immediate (TN *dest, TN *src, BOOL is_signed, OPS *ops)
00270 {
00271 Expand_Immediate(dest, src, is_signed, ops);
00272 }
00273
00274
00275
00276
00277 void
00278 Expand_Immediate (TN *dest, TN *src, BOOL is_signed, OPS *ops)
00279 {
00280 FmtAssert((TN_is_constant(src)),
00281 ("unexpected non-constant in Expand_Immediate"));
00282 FmtAssert((TN_has_value(src) || TN_is_symbol(src)),
00283 ("expected value or const in Expand_Immediate"));
00284 Exp_Immediate (dest, src, ops);
00285 }
00286
00287 TN*
00288 Expand_Immediate_Into_Register (TN *src, BOOL is_64bit, OPS *ops)
00289 {
00290 if (TN_value(src) == 0)
00291 return Zero_TN;
00292
00293 TN *tmp = Build_TN_Of_Mtype (is_64bit ? MTYPE_I8 : MTYPE_I4);
00294 Expand_Immediate (tmp, src, TRUE, ops);
00295 return tmp;
00296 }
00297
00298 void
00299 Expand_Add (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00300 {
00301 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
00302 ("Expand_Add: illegal result size\n"));
00303 TOP new_opcode;
00304 INT64 val;
00305 BOOL is_64bit = MTYPE_bit_size(mtype) == 64;
00306 if (TN_is_constant(src1)) {
00307 if (TN_has_value(src1)) {
00308 val = TN_value(src1);
00309 if (val == 0) {
00310 Expand_Copy (result, src2, mtype, ops);
00311 return;
00312 }
00313 } else if ( TN_is_symbol(src1) ) {
00314
00315 ST *base;
00316 INT64 val;
00317 TN *tmp = Build_TN_Of_Mtype (mtype);
00318 Base_Symbol_And_Offset_For_Addressing (TN_var(src1), TN_offset(src1),
00319 &base, &val);
00320 new_opcode = is_64bit ? TOP_daddiu : TOP_addiu;
00321 if (ISA_LC_Value_In_Class (val, LC_simm16) ||
00322 ISA_LC_Value_In_Class (val, LC_uimm16)) {
00323 Build_OP (new_opcode, result, src2, src1, ops);
00324 } else if (val >= INT32_MIN && val <= INT32_MAX) {
00325 Build_OP (TOP_lui, tmp, Gen_Literal_TN((val >> 16)&0xffff, 4), ops);
00326 Build_OP (TOP_ori, tmp, tmp, Gen_Literal_TN(val & 0xffff, 4), ops);
00327 Build_OP (is_64bit ? TOP_daddu : TOP_addu, result, tmp, src2, ops);
00328 } else {
00329 TCON tcon = Host_To_Targ (MTYPE_I8, val);
00330 ST *sym = New_Const_Sym (Enter_tcon (tcon), Be_Type_Tbl(MTYPE_I8));
00331 Allocate_Object(sym);
00332 if (Use_32_Bit_Pointers)
00333 Build_OP(TOP_lw, tmp, GP_TN,
00334 Gen_Symbol_TN(sym, 0, TN_RELOC_GOT_DISP), ops);
00335 else {
00336 Build_OP(TOP_ld, tmp, GP_TN,
00337 Gen_Symbol_TN(sym, 0, TN_RELOC_GOT_DISP), ops);
00338 }
00339 Build_OP(TOP_ld, tmp, tmp, Gen_Literal_TN(0, 4), ops);
00340 Build_OP (is_64bit ? TOP_daddu : TOP_addu, result, tmp, src2, ops);
00341 }
00342 return;
00343 }
00344 else FmtAssert(FALSE,("unexpected constant in Expand_Add"));
00345
00346 if (ISA_LC_Value_In_Class ( val, LC_simm16)) {
00347 new_opcode = is_64bit ? TOP_daddiu : TOP_addiu;
00348 Build_OP (new_opcode, result, src2, Gen_Literal_TN(val,4), ops);
00349 } else {
00350 src1 = Expand_Immediate_Into_Register (src1, is_64bit, ops);
00351 new_opcode = is_64bit ? TOP_dadd : TOP_addu;
00352 Build_OP (new_opcode, result, src2, src1, ops);
00353 }
00354 } else if (TN_is_constant(src2)) {
00355
00356 Expand_Add (result, src2, src1, mtype, ops);
00357 } else {
00358 Build_OP (is_64bit ? TOP_daddu : TOP_addu, result, src1, src2, ops);
00359 }
00360 }
00361
00362 void
00363 Expand_Sub (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
00364 {
00365 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
00366 ("Expand_Sub: illegal result size\n"));
00367 TOP new_opcode;
00368 INT64 val;
00369 BOOL is_64bit = MTYPE_bit_size(mtype) == 64;
00370 if (TN_is_constant(src2)) {
00371 if (TN_has_value(src2)) {
00372 val = - TN_value(src2);
00373 if (val == 0) {
00374 Expand_Copy (result, src1, mtype, ops);
00375 return;
00376 }
00377 }
00378 else if ( TN_is_symbol(src2) ) {
00379
00380 ST *base;
00381 INT64 val;
00382 Base_Symbol_And_Offset_For_Addressing (TN_var(src2), TN_offset(src2), &base, &val);
00383 val = - val;
00384 }
00385 else FmtAssert(FALSE,("unexpected constant in Expand_Sub"));
00386
00387 if (ISA_LC_Value_In_Class ( val, LC_simm16)) {
00388 new_opcode = is_64bit ? TOP_daddiu : TOP_addiu;
00389 Build_OP (new_opcode, result, src1, Gen_Literal_TN(val,4), ops);
00390 } else {
00391 src2 = Expand_Immediate_Into_Register (src2, is_64bit, ops);
00392 new_opcode = is_64bit ? TOP_dsubu : TOP_subu;
00393 Build_OP (new_opcode, result, src1, src2, ops);
00394 }
00395 }
00396 else if (TN_is_constant(src1)) {
00397 TN *tmp = Build_TN_Of_Mtype (mtype);
00398
00399 Expand_Sub (tmp, src2, src1, mtype, ops);
00400
00401 Build_OP(is_64bit ? TOP_dsubu : TOP_subu, result, Zero_TN, tmp, ops);
00402 }
00403 else {
00404 Build_OP (is_64bit ? TOP_dsubu : TOP_subu, result, src1, src2, ops);
00405 }
00406 }
00407
00408
00409 void
00410 Expand_Neg (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
00411 {
00412 BOOL is_64bit = MTYPE_bit_size(mtype) == 64;
00413 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
00414 ("Expand_Neg: illegal result size\n"));
00415 Build_OP (is_64bit ? TOP_dsubu : TOP_subu, result, Zero_TN, src, ops);
00416 }
00417
00418 void
00419 Expand_Abs (TN *dest, TN *src, TYPE_ID mtype, OPS *ops)
00420 {
00421
00422 if (mtype == MTYPE_U4 || mtype == MTYPE_U8){
00423 DevWarn("Try to get Abs value of an unsigned number!\n");
00424 Expand_Copy(dest, src, mtype, ops);
00425 return;
00426 }
00427
00428 TN *tmp1, *tmp2;
00429 tmp1 = Build_TN_Like(dest);
00430 tmp2 = Build_TN_Like(dest);
00431
00432 if (mtype == MTYPE_I8) {
00433 Build_OP(TOP_dsra32, tmp1, src, Gen_Literal_TN(31, 2), ops);
00434 Build_OP(TOP_xor, tmp2, src, tmp1, ops);
00435 Build_OP(TOP_dsub, dest, tmp2, tmp1, ops);
00436 } else if (mtype == MTYPE_I4) {
00437 Build_OP(TOP_sra, tmp1, src, Gen_Literal_TN(31, 2), ops);
00438 Build_OP(TOP_xor, tmp2, src, tmp1, ops);
00439 Build_OP(TOP_sub, dest, tmp2, tmp1, ops);
00440 } else {
00441 Is_True(FALSE, ("Can not handle this ABS case!\n"));
00442 }
00443
00444 #if 0
00445 TN *p1 = Build_TN_Of_Mtype(MTYPE_I4);
00446 BOOL is_signed = MTYPE_is_signed(mtype);
00447 BOOL is_double = MTYPE_is_size_double(mtype);
00448 if (src != dest) {
00449 Build_OP(is_double ? TOP_dsubu : TOP_subu, dest, Zero_TN, src, ops);
00450 Build_OP(is_signed?TOP_slt:TOP_sltu, p1, src, Zero_TN, ops);
00451 Build_OP(TOP_movz, dest, src, p1, ops);
00452 }
00453 else {
00454 TN *tmp = Build_TN_Of_Mtype(mtype);
00455 Build_OP(is_double ? TOP_dsubu : TOP_subu, tmp, Zero_TN, src, ops);
00456 Build_OP(is_signed?TOP_slt:TOP_sltu, p1, src, Zero_TN, ops);
00457 Build_OP(TOP_movn, dest, tmp, p1, ops);
00458 }
00459 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_UNC_DEF);
00460 #endif
00461 }
00462
00463 void
00464 Expand_Shift (TN *result, TN *src1, TN *src2, TYPE_ID mtype, SHIFT_DIRECTION kind, OPS *ops)
00465 {
00466 WN *tree;
00467 TOP top;
00468 BOOL is_64bit = MTYPE_is_size_double(mtype);
00469
00470
00471 if (TN_is_constant(src1))
00472 src1 = Expand_Immediate_Into_Register(src1, MTYPE_is_size_double(mtype), ops);
00473 if (TN_has_value(src2)) {
00474
00475 UINT64 val = TN_value(src2);
00476 switch (kind) {
00477 case shift_left:
00478 if (! is_64bit)
00479 top = TOP_sll;
00480 else if (val < 32)
00481 top = TOP_dsll;
00482 else top = TOP_dsll32;
00483 break;
00484 case shift_aright:
00485 if (! is_64bit)
00486 top = TOP_sra;
00487 else if (val < 32)
00488 top = TOP_dsra;
00489 else top = TOP_dsra32;
00490 break;
00491 case shift_lright:
00492 if (! is_64bit)
00493 top = TOP_srl;
00494 else if (val < 32)
00495 top = TOP_dsrl;
00496 else top = TOP_dsrl32;
00497 break;
00498 }
00499 Build_OP(top, result, src1, Gen_Literal_TN(val & 31, 4), ops);
00500 }
00501 else {
00502 switch (kind) {
00503 case shift_left:
00504 top = is_64bit ? TOP_dsllv : TOP_sllv;
00505 break;
00506
00507 case shift_aright:
00508 top = is_64bit ? TOP_dsrav : TOP_srav;
00509 break;
00510
00511 case shift_lright:
00512 top = is_64bit ? TOP_dsrlv : TOP_srlv;
00513 break;
00514 }
00515 Build_OP(top, result, src1, src2, ops);
00516 }
00517 }
00518
00519 inline void
00520 Expand_G_To_F (TN *ftn, TN *gtn, OPS *ops)
00521 { FmtAssert(FALSE,("Unimplemented")); }
00522
00523 inline void
00524 Expand_F_To_G (TN *gtn, TN *ftn, OPS *ops)
00525 { FmtAssert(FALSE,("Unimplemented")); }
00526
00527
00528
00529
00530
00531
00532
00533 static void shladd(TN *r, TN *x1, INT s, TN *x2, OPS *ops)
00534 {
00535 FmtAssert(s <= 31,("shladd: shift amount too large: %d",s));
00536 if (x2 == Zero_TN) {
00537 Build_OP(TN_size(r) == 8 ? TOP_dsll : TOP_sll, r, x1, Gen_Literal_TN(s, 4),
00538 ops);
00539 }
00540 else {
00541 TN *tmp_tn = Build_TN_Like(r);
00542 if (TN_size(r) == 8) {
00543 Build_OP(TOP_dsll, tmp_tn, x1, Gen_Literal_TN(s, 4), ops);
00544 Build_OP(TOP_daddu, r, tmp_tn, x2, ops);
00545 } else {
00546 Build_OP(TOP_sll, tmp_tn, x1, Gen_Literal_TN(s, 4), ops);
00547 Build_OP(TOP_addu, r, tmp_tn, x2, ops);
00548 }
00549 }
00550 }
00551
00552
00553
00554
00555
00556
00557
00558
00559 static void
00560 Expand_Small_Multiply(TN *r,
00561 TN *x,
00562 INT16 val,
00563 OPS * ops)
00564 {
00565 TN *r1;
00566 TN *r2;
00567 TN *Z=Zero_TN;
00568
00569 #define ONE_TEMP r1=Build_TN_Like(r)
00570 #define TWO_TEMPS ONE_TEMP; r2=Build_TN_Like(r)
00571
00572
00573 switch (val) {
00574 case -1:
00575 Expand_Neg(r,x,MTYPE_I8,ops);
00576 break;
00577 case 0:
00578 Expand_Copy (r, Z, MTYPE_I8, ops);
00579 break;
00580 case 1 :
00581 Expand_Copy (r, x, MTYPE_I8, ops);
00582 break;
00583 case 2 :
00584 shladd(r,x,1,Z,ops);
00585 break;
00586 case 3 :
00587 shladd(r,x,1,x,ops);
00588 break;
00589 case 4 :
00590 shladd(r,x,2,Z,ops);
00591 break;
00592 case 5 :
00593 shladd(r,x,2,x,ops);
00594 break;
00595 case 6:
00596 ONE_TEMP;
00597 Expand_Small_Multiply(r1,x,3,ops);
00598 Expand_Small_Multiply(r,r1,2,ops);
00599 break;
00600 case 7 :
00601 ONE_TEMP;
00602 shladd(r1,x,1,x,ops);
00603 shladd(r,r1,1,x,ops);
00604 break;
00605 case 8 :
00606 shladd(r,x,3,Z,ops);
00607 break;
00608 case 9 :
00609 shladd(r,x,3,x,ops);
00610 break;
00611 case 10 :
00612 ONE_TEMP;
00613 Expand_Small_Multiply(r1,x,5,ops);
00614 Expand_Small_Multiply(r,r1,2,ops);
00615 break;
00616 case 11 :
00617 ONE_TEMP;
00618 Expand_Small_Multiply(r1,x,9,ops);
00619 shladd(r,x,1,r1,ops);
00620 break;
00621 case 12 :
00622 ONE_TEMP;
00623 Expand_Small_Multiply(r1,x,3,ops);
00624 Expand_Small_Multiply(r,r1,4,ops);
00625 break;
00626 case 13 :
00627 ONE_TEMP;
00628 Expand_Small_Multiply(r1,x,5,ops);
00629 shladd(r,x,3,r1,ops);
00630 break;
00631 case 14 :
00632 TWO_TEMPS;
00633 Expand_Small_Multiply(r1,x,5,ops);
00634 Expand_Small_Multiply(r2,x,9,ops);
00635 Expand_Add(r,r1,r2,MTYPE_I8,ops);
00636 break;
00637 case 15 :
00638 ONE_TEMP;
00639 Expand_Small_Multiply(r1,x,3,ops);
00640 Expand_Small_Multiply(r,r1,5,ops);
00641 break;
00642 case 16 :
00643 shladd(r,x,4,Z,ops);
00644 break;
00645 case 17 :
00646 shladd(r,x,4,x,ops);
00647 break;
00648 case 18 :
00649 ONE_TEMP;
00650 Expand_Small_Multiply(r1,x,9,ops);
00651 Expand_Small_Multiply(r,r1,2,ops);
00652 break;
00653 case 19 :
00654 ONE_TEMP;
00655 Expand_Small_Multiply(r1,x,9,ops);
00656 shladd(r,r1,1,x,ops);
00657 break;
00658 case 20 :
00659 ONE_TEMP;
00660 Expand_Small_Multiply(r1,x,5,ops);
00661 Expand_Small_Multiply(r,r1,4,ops);
00662 break;
00663 case 21 :
00664 ONE_TEMP;
00665 Expand_Small_Multiply(r1,x,5,ops);
00666 shladd(r,x,4,r1,ops);
00667 break;
00668 case 22 :
00669 TWO_TEMPS;
00670 Expand_Small_Multiply(r1,x,17,ops);
00671 Expand_Small_Multiply(r2,x,5,ops);
00672 Expand_Add(r,r1,r2,MTYPE_I8,ops);
00673 break;
00674 case 23 :
00675 TWO_TEMPS;
00676 Expand_Small_Multiply(r1,x,17,ops);
00677 Expand_Small_Multiply(r2,x,3,ops);
00678 shladd(r,r2,1,r1,ops);
00679 break;
00680 case 24 :
00681 ONE_TEMP;
00682 Expand_Small_Multiply(r1,x,3,ops);
00683 Expand_Small_Multiply(r,r1,8,ops);
00684 break;
00685 case 25 :
00686 ONE_TEMP;
00687 Expand_Small_Multiply(r1,x,5,ops);
00688 Expand_Small_Multiply(r,r1,5,ops);
00689 break;
00690 case 26 :
00691 TWO_TEMPS;
00692 Expand_Small_Multiply(r1,x,17,ops);
00693 Expand_Small_Multiply(r2,x,9,ops);
00694 Expand_Add(r,r1,r2,MTYPE_I8,ops);
00695 break;
00696 case 27 :
00697 ONE_TEMP;
00698 Expand_Small_Multiply(r1,x,9,ops);
00699 Expand_Small_Multiply(r,r1,3,ops);
00700 break;
00701 case 28 :
00702 TWO_TEMPS;
00703 Expand_Small_Multiply(r1,x,3,ops);
00704 Expand_Small_Multiply(r2,x,4,ops);
00705 shladd(r,r1,3,r2,ops);
00706 break;
00707 case 29 :
00708 TWO_TEMPS;
00709 Expand_Small_Multiply(r1,x,3,ops);
00710 Expand_Small_Multiply(r2,x,5,ops);
00711 shladd(r,r1,3,r2,ops);
00712 break;
00713 case 30 :
00714 ONE_TEMP;
00715 Expand_Small_Multiply(r1,x,15,ops);
00716 Expand_Small_Multiply(r,r1,2,ops);
00717 break;
00718 case 31 :
00719 TWO_TEMPS;
00720 Expand_Small_Multiply(r1,x,16,ops);
00721 Expand_Small_Multiply(r2,x,-1,ops);
00722 shladd(r,r1,1,r2,ops);
00723 break;
00724 case 32 :
00725 ONE_TEMP;
00726 Expand_Small_Multiply(r1,x,16,ops);
00727 Expand_Small_Multiply(r,r1,2,ops);
00728 break;
00729 case 33 :
00730 ONE_TEMP;
00731 Expand_Small_Multiply(r1,x,16,ops);
00732 shladd(r,r1,1,x,ops);
00733 break;
00734 case 34 :
00735 ONE_TEMP;
00736 Expand_Small_Multiply(r1,x,17,ops);
00737 Expand_Small_Multiply(r,r1,2,ops);
00738 break;
00739 case 35 :
00740 ONE_TEMP;
00741 Expand_Small_Multiply(r1,x,17,ops);
00742 shladd(r,r1,1,x,ops);
00743 break;
00744 case 36 :
00745 ONE_TEMP;
00746 Expand_Small_Multiply(r1,x,9,ops);
00747 Expand_Small_Multiply(r,r1,4,ops);
00748 break;
00749 case 37 :
00750 ONE_TEMP;
00751 Expand_Small_Multiply(r1,x,9,ops);
00752 shladd(r,r1,2,x,ops);
00753 break;
00754 case 38 :
00755 TWO_TEMPS;
00756 Expand_Small_Multiply(r1,x,17,ops);
00757 Expand_Small_Multiply(r2,x,4,ops);
00758 shladd(r,r1,1,r2,ops);
00759 break;
00760 case 39 :
00761 TWO_TEMPS;
00762 Expand_Small_Multiply(r1,x,17,ops);
00763 Expand_Small_Multiply(r2,x,5,ops);
00764 shladd(r,r1,1,r2,ops);
00765 break;
00766 case 40 :
00767 ONE_TEMP;
00768 Expand_Small_Multiply(r1,x,5,ops);
00769 Expand_Small_Multiply(r,r1,8,ops);
00770 break;
00771 case 41 :
00772 ONE_TEMP;
00773 Expand_Small_Multiply(r1,x,5,ops);
00774 shladd(r,r1,3,x,ops);
00775 break;
00776 case 42 :
00777 TWO_TEMPS;
00778 Expand_Small_Multiply(r1,x,5,ops);
00779 Expand_Small_Multiply(r2,x,2,ops);
00780 shladd(r,r1,3,r2,ops);
00781 break;
00782 case 43 :
00783 TWO_TEMPS;
00784 Expand_Small_Multiply(r1,x,5,ops);
00785 Expand_Small_Multiply(r2,x,3,ops);
00786 shladd(r,r1,3,r2,ops);
00787 break;
00788 case 44 :
00789 TWO_TEMPS;
00790 Expand_Small_Multiply(r1,x,5,ops);
00791 Expand_Small_Multiply(r2,x,4,ops);
00792 shladd(r,r1,3,r2,ops);
00793 break;
00794 case 45 :
00795 ONE_TEMP;
00796 Expand_Small_Multiply(r1,x,5,ops);
00797 Expand_Small_Multiply(r,r1,9,ops);
00798 break;
00799 case 46 :
00800 ONE_TEMP;
00801 Expand_Small_Multiply(r1,x,45,ops);
00802 Expand_Add(r,r1,x,MTYPE_I8,ops);
00803 break;
00804 case 47 :
00805 TWO_TEMPS;
00806 Expand_Small_Multiply(r1,x,-1,ops);
00807 Expand_Small_Multiply(r2,x,3,ops);
00808 shladd(r,r2,4,r1,ops);
00809 break;
00810 case 48 :
00811 ONE_TEMP;
00812 Expand_Small_Multiply(r1,x,3,ops);
00813 Expand_Small_Multiply(r,r1,16,ops);
00814 break;
00815 case 49 :
00816 ONE_TEMP;
00817 Expand_Small_Multiply(r1,x,3,ops);
00818 shladd(r,r1,4,x,ops);
00819 break;
00820 case 50 :
00821 TWO_TEMPS;
00822 Expand_Small_Multiply(r1,x,3,ops);
00823 Expand_Small_Multiply(r2,x,2,ops);
00824 shladd(r,r1,4,r2,ops);
00825 break;
00826 case 51 :
00827 ONE_TEMP;
00828 Expand_Small_Multiply(r1,x,3,ops);
00829 Expand_Small_Multiply(r,r1,17,ops);
00830 break;
00831 case 52 :
00832 TWO_TEMPS;
00833 Expand_Small_Multiply(r1,x,3,ops);
00834 Expand_Small_Multiply(r2,x,4,ops);
00835 shladd(r,r1,4,r2,ops);
00836 break;
00837 case 53 :
00838 TWO_TEMPS;
00839 Expand_Small_Multiply(r1,x,3,ops);
00840 Expand_Small_Multiply(r2,x,5,ops);
00841 shladd(r,r1,4,r2,ops);
00842 break;
00843 case 54 :
00844 ONE_TEMP;
00845 Expand_Small_Multiply(r1,x,9,ops);
00846 Expand_Small_Multiply(r,r1,6,ops);
00847 break;
00848 case 55 :
00849 ONE_TEMP;
00850 Expand_Small_Multiply(r1,x,11,ops);
00851 Expand_Small_Multiply(r,r1,5,ops);
00852 break;
00853 case 56 :
00854 TWO_TEMPS;
00855 Expand_Small_Multiply(r1,x,3,ops);
00856 Expand_Small_Multiply(r2,x,8,ops);
00857 shladd(r,r1,4,r2,ops);
00858 break;
00859 case 57 :
00860 TWO_TEMPS;
00861 Expand_Small_Multiply(r1,x,3,ops);
00862 Expand_Small_Multiply(r2,x,9,ops);
00863 shladd(r,r1,4,r2,ops);
00864 break;
00865 case 58 :
00866 ONE_TEMP;
00867 Expand_Small_Multiply(r1,x,29,ops);
00868 Expand_Small_Multiply(r,r1,2,ops);
00869 break;
00870 case 59 :
00871 ONE_TEMP;
00872 Expand_Small_Multiply(r1,x,29,ops);
00873 shladd(r,r1,1,x,ops);
00874 break;
00875 case 60 :
00876 ONE_TEMP;
00877 Expand_Small_Multiply(r1,x,12,ops);
00878 Expand_Small_Multiply(r,r1,5,ops);
00879 break;
00880 case 61 :
00881 ONE_TEMP;
00882 Expand_Small_Multiply(r1,x,45,ops);
00883 shladd(r,x,4,r1,ops);
00884 break;
00885 case 62 :
00886 ONE_TEMP;
00887 Expand_Small_Multiply(r1,x,31,ops);
00888 Expand_Small_Multiply(r,r1,2,ops);
00889 break;
00890 case 63 :
00891 TWO_TEMPS;
00892 Expand_Small_Multiply(r1,x,-1,ops);
00893 Expand_Small_Multiply(r2,x,16,ops);
00894 shladd(r,r2,2,r1,ops);
00895 break;
00896 default:
00897 #pragma mips_frequency_hint NEVER
00898 FmtAssert(0,("Can't small multiply by %d",val));
00899
00900 }
00901 }
00902
00903
00904
00905
00906
00907
00908 static BOOL
00909 Expand_Multiply_Into_Shifts (
00910 TN *result_tn,
00911 TN *var_tn,
00912 TARG_UINT constant,
00913 INT16 limit,
00914 TYPE_ID mtype,
00915 OPS *ops)
00916 { FmtAssert(FALSE,("Unimplemented")); }
00917
00918
00919
00920
00921 #define NUM_FAST_MPYS 8
00922 static INT fast_mpys[NUM_FAST_MPYS] = {17,16,9,8,5,4,3,2};
00923
00924 static BOOL
00925 Expand_Constant_Multiply (TN *result, TN *var_tn, TARG_INT constant, TYPE_ID mtype, OPS *ops)
00926 {
00927 BOOL did_do_fast;
00928 INT16 limit;
00929 TN *x = var_tn;
00930 TN *r1 = Build_TN_Like(result);
00931 INT64 c = constant;
00932 BOOL needs_sign_extension;
00933
00934
00935 if (c == 0) {
00936 Expand_Copy (result, Zero_TN, mtype, ops);
00937 return TRUE;
00938 } else if (c == 1) {
00939 Expand_Copy (result, var_tn, mtype, ops);
00940 return TRUE;
00941 } else if (c == -1) {
00942 Expand_Neg(result, var_tn, mtype, ops);
00943 return TRUE;
00944 }
00945
00946 if (c < 0) {
00947 c = -c;
00948 x = Build_TN_Like(var_tn);
00949 Expand_Neg(x, var_tn, mtype, ops);
00950 }
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960 #if defined(TARG_SL)
00961 needs_sign_extension = MTYPE_size_reg(mtype) != 32;
00962 BOOL matched = FALSE;
00963 if(c<=5) {
00964 switch(c) {
00965 case 2:
00966 Expand_Shift(result, x, Gen_Literal_TN(1, 4), mtype, shift_left, ops);
00967 break;
00968 case 3:
00969 Expand_Shift(r1, x, Gen_Literal_TN(1, 4), mtype, shift_left, ops);
00970 Expand_Add(result, r1, x, mtype,ops);
00971 break;
00972 case 4:
00973 Expand_Shift(result, x, Gen_Literal_TN(2, 4), mtype, shift_left, ops);
00974 break;
00975 case 5:
00976 Expand_Shift(r1, x, Gen_Literal_TN(2, 4), mtype, shift_left, ops);
00977 Expand_Add(result, r1, x, mtype,ops);
00978 break;
00979 }
00980 matched = TRUE;
00981 }
00982 else {
00983 UINT shift_bit;
00984 UINT word_bit = HOST_WORD_SIZE * 8;
00985 for(shift_bit = 3; shift_bit<word_bit&&matched==FALSE; shift_bit++) {
00986 UINT sNumber = 1 << shift_bit;
00987 if(sNumber==c) {
00988 Expand_Shift(result, x, Gen_Literal_TN(shift_bit, 4), mtype, shift_left, ops);
00989 matched = TRUE;
00990 }
00991 else if(sNumber-1==c) {
00992 Expand_Shift(r1, x, Gen_Literal_TN(shift_bit, 4), mtype, shift_left, ops);
00993 Expand_Sub(result, r1, x, mtype,ops);
00994 matched = TRUE;
00995 }
00996 else if(sNumber+1==c) {
00997 Expand_Shift(r1, x, Gen_Literal_TN(shift_bit, 4), mtype, shift_left, ops);
00998 Expand_Add(result, r1, x, mtype,ops);
00999 matched = TRUE;
01000 }
01001 else if(sNumber-2==c) {
01002 Expand_Shift(r1, x, Gen_Literal_TN(shift_bit, 4), mtype, shift_left, ops);
01003 Expand_Sub(r1, r1, x,mtype,ops);
01004 Expand_Sub(result, r1, x, mtype,ops);
01005 matched = TRUE;
01006 }
01007 else if(sNumber+2==c) {
01008 Expand_Shift(r1, x, Gen_Literal_TN(shift_bit, 4), mtype, shift_left, ops);
01009 Expand_Add(r1, r1, x, mtype,ops);
01010 Expand_Add(result, r1, x, mtype,ops);
01011 matched = TRUE;
01012 }
01013 }
01014 }
01015 if(matched==TRUE) {
01016 if (needs_sign_extension) {
01017 TN *r2 = Build_TN_Like(result);
01018 Expand_Copy (r2, result, mtype, ops);
01019 Fixup_32_Bit_Op(result,r2,mtype,ops);
01020 }
01021 return TRUE;
01022 }
01023 else {
01024 return FALSE;
01025 }
01026
01027
01028
01029
01030 #else
01031
01032
01033 INT num_ones=0;
01034 UINT64 uc=c;
01035 while (uc) {num_ones += (uc&1); uc >>= 1;}
01036 uc = c;
01037 needs_sign_extension = MTYPE_size_reg(mtype) != 64;
01038
01039
01040
01041 if (uc <= 63) {
01042 if (needs_sign_extension) {
01043 Expand_Small_Multiply(result,x,uc,ops);
01044 } else {
01045 TN *r1 = Build_TN_Of_Mtype(MTYPE_I8);
01046 Expand_Small_Multiply(r1,x,uc,ops);
01047 Fixup_32_Bit_Op(result, r1, mtype,ops);
01048 }
01049 return TRUE;
01050 }
01051
01052
01053
01054
01055
01056
01057 INT first_1 = 0;
01058 while ((uc & 1) == 0) {++first_1; uc >>= 1;}
01059 if (first_1 != 0) {
01060 if (num_ones == 1) {
01061
01062 Expand_Shift(result, x, Gen_Literal_TN(first_1, 4), mtype, shift_left, ops);
01063 return TRUE;
01064 } else {
01065 TN *x1 = Dup_TN(x);
01066 Expand_Shift(x1, x, Gen_Literal_TN(first_1, 4), MTYPE_I8, shift_left, ops);
01067 x = x1;
01068 }
01069 }
01070
01071
01072
01073
01074
01075
01076
01077 if (uc == ((1<<num_ones)-1) && uc > 63) {
01078 TN *r1 = Dup_TN(result);
01079 Expand_Shift(r1, x, Gen_Literal_TN(num_ones, 4), MTYPE_I8, shift_left, ops);
01080 if (!needs_sign_extension) {
01081 Expand_Sub(result,r1,x,mtype,ops);
01082 } else {
01083 TN *r2 = Dup_TN(result);
01084 Expand_Sub(r2,r1,x,mtype,ops);
01085 Fixup_32_Bit_Op(result,r2,mtype,ops);
01086 }
01087 return TRUE;
01088 }
01089
01090
01091
01092
01093
01094 INT i;
01095 for (i=0; i < NUM_FAST_MPYS; i++) {
01096 INT mpy=fast_mpys[i];
01097 if (uc%mpy == 0 && uc/mpy <= 63) {
01098 INT64 uc1;
01099 TN *r1 = Dup_TN(result);
01100 Expand_Small_Multiply(r1,x,uc/mpy,ops);
01101 Expand_Constant_Multiply(result,r1,mpy,mtype,ops);
01102 return TRUE;
01103 }
01104 }
01105
01106
01107
01108
01109 TN *r = result;
01110 if (needs_sign_extension) {
01111 r = Dup_TN(result);
01112 }
01113
01114
01115
01116
01117
01118
01119 if (uc <= 63) {
01120 Expand_Small_Multiply(r,x,uc,ops);
01121 } else if (uc <= 1023) {
01122 INT64 uc1,uc2;
01123 TN *r1 = Dup_TN(result);
01124
01125
01126 uc1 = uc & 15;
01127 uc2 = uc >> 4;
01128
01129 Expand_Small_Multiply(r1,x,uc2,ops);
01130 if (uc1 == 0) {
01131 shladd(r,r1,4,Zero_TN,ops);
01132 } else if (uc1 == 1) {
01133 shladd(r,r1,4,x,ops);
01134 } else if (uc1 == uc2) {
01135 shladd(r,r1,4,r1,ops);
01136 } else {
01137 TN *r2 = Dup_TN(result);
01138 Expand_Small_Multiply(r2,x,uc1,ops);
01139 shladd(r,r1,4,r2,ops);
01140 }
01141 } else if (uc <= 65535) {
01142
01143
01144
01145
01146
01147
01148
01149 INT64 uc1,uc2;
01150 TN *r1 = Dup_TN(result);
01151 TN *r2 = Dup_TN(result);
01152 uc1 = uc & 255;
01153 uc2 = uc >> 8;
01154 Expand_Constant_Multiply (r1, x, uc2, MTYPE_I8, ops);
01155 if (uc1 == 0) {
01156 shladd(r2,r1,4,Zero_TN,ops);
01157 shladd(r,r2,4,Zero_TN,ops);
01158 } else if (uc1 == 1) {
01159 shladd(r2,r1,4,Zero_TN,ops);
01160 shladd(r,r2,4,x,ops);
01161
01162 } else if (uc1 == 16) {
01163 shladd(r2,r1,4,x,ops);
01164 shladd(r,r2,4,Zero_TN,ops);
01165
01166 } else if (uc1 == 17) {
01167 shladd(r2,r1,4,x,ops);
01168 shladd(r,r2,4,x,ops);
01169
01170 } else if (uc1 == uc2) {
01171 shladd(r2,r1,4,Zero_TN,ops);
01172 shladd(r,r2,4,r1,ops);
01173
01174 } else if (uc1 == 16*uc2) {
01175 shladd(r2,r1,4,r1,ops);
01176 shladd(r,r2,4,Zero_TN,ops);
01177
01178 } else if (uc1 == 17*uc2) {
01179 shladd(r2,r1,4,r1,ops);
01180 shladd(r,r2,4,r1,ops);
01181
01182 } else if (uc1%16 == 0) {
01183 TN *r3 = Dup_TN(result);
01184 uc1 /= 16;
01185 Expand_Constant_Multiply(r3,x,uc1,MTYPE_I8,ops);
01186 shladd(r2,r1,4,r3,ops);
01187 shladd(r,r2,4,Zero_TN,ops);
01188
01189 } else if (uc1%17 == 0) {
01190 TN *r3 = Dup_TN(result);
01191 uc1 /= 17;
01192 Expand_Constant_Multiply(r3,x,uc1,MTYPE_I8,ops);
01193 shladd(r2,r1,4,r3,ops);
01194 shladd(r,r2,4,r3,ops);
01195
01196 } else {
01197 TN *r3 = Dup_TN(result);
01198 Expand_Constant_Multiply(r3,x,uc1,MTYPE_I8,ops);
01199 shladd(r2,r1,4,Zero_TN,ops);
01200 shladd(r,r2,4,r3,ops);
01201 }
01202 } else if (uc <= ((1LL << 32)-1)) {
01203
01204
01205
01206
01207 INT64 uc1,uc2;
01208 TN *r1 = Dup_TN(result);
01209 TN *r2 = Dup_TN(result);
01210 TN *r3 = Dup_TN(result);
01211 uc1 = uc & 65535;
01212 uc2 = uc >> 16;
01213 Expand_Constant_Multiply(r1,x,uc1,MTYPE_I8,ops);
01214 Expand_Constant_Multiply(r2,x,uc2,MTYPE_I8,ops);
01215 Expand_Shift(r3,r2,Gen_Literal_TN(16, 4),MTYPE_I8,shift_left,ops);
01216 Expand_Add(r,r1,r3,MTYPE_I8,ops);
01217 } else {
01218
01219
01220
01221
01222
01223
01224
01225 INT64 uc1,uc2;
01226 TN *r1 = Dup_TN(result);
01227 TN *r2 = Dup_TN(result);
01228 TN *r3 = Dup_TN(result);
01229 uc1 = uc & 0xffffffff;
01230 uc2 = uc >> 32;
01231 Expand_Constant_Multiply(r1,x,uc1,MTYPE_I8,ops);
01232 Expand_Constant_Multiply(r2,x,uc2,MTYPE_I8,ops);
01233 Expand_Shift(r3,r2,Gen_Literal_TN(32, 4),MTYPE_I8,shift_left,ops);
01234 Expand_Add(r,r1,r3,MTYPE_I8,ops);
01235 }
01236
01237 if (needs_sign_extension) {
01238 Fixup_32_Bit_Op(result,r,mtype,ops);
01239 }
01240
01241 return TRUE;
01242 #endif // TARG_SL
01243 }
01244
01245 void
01246 Expand_Multiply (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01247 {
01248 TOP top;
01249 INT64 constant;
01250
01251
01252
01253
01254 if ((TN_has_value(src1) || TN_is_rematerializable(src1)) &&
01255 (TN_has_value(src2) || TN_is_rematerializable(src2))) {
01256
01257 TN *val_tn;
01258 constant = TN_has_value(src1) ? TN_value(src1) : WN_const_val(TN_home(src1));
01259 constant *= TN_has_value(src2) ? TN_value(src2) : WN_const_val(TN_home(src2));
01260
01261 constant = Targ_To_Host(Host_To_Targ(mtype,constant));
01262 #if defined(TARG_SL)
01263 val_tn = Gen_Literal_TN(constant, 4);
01264 #else
01265 val_tn = Gen_Literal_TN(constant, 8);
01266 #endif
01267 Exp_Immediate(result,val_tn,MTYPE_is_signed(mtype),ops);
01268 return;
01269 }
01270
01271 if (!Disable_Const_Mult_Opt && (TN_has_value(src1) || TN_has_value(src2) ||
01272 TN_is_rematerializable(src1) ||TN_is_rematerializable(src2))) {
01273 TN *var_tn;
01274 if ( TN_has_value(src1) || TN_is_rematerializable(src1) ) {
01275 constant = TN_has_value(src1) ? TN_value(src1) : WN_const_val(TN_home(src1));
01276 var_tn = src2;
01277 }
01278 else {
01279 constant = TN_has_value(src2) ? TN_value(src2) : WN_const_val(TN_home(src2));
01280 var_tn = src1;
01281 }
01282
01283 if (Can_Do_Fast_Multiply (mtype, constant)) {
01284 if (Expand_Constant_Multiply (result, var_tn, constant, mtype, ops)) {
01285
01286 return;
01287 }
01288 }
01289 }
01290 if (TN_has_value(src2)) {
01291 src2 = Expand_Immediate_Into_Register (src2, MTYPE_is_size_double(mtype), ops);
01292 }
01293
01294 FmtAssert(!TN_is_constant(src1),("Expand_Multiply: unexpected constant operand"));
01295 #if defined(TARG_SL)
01296 Is_True(!(MTYPE_is_size_double(mtype)), ("Expand_Multiply: unsupport 64-bit compute"));
01297
01298 if (CG_sl2) {
01299 top = TOP_c2_muls;
01300 } else {
01301 top = MTYPE_signed(mtype) ? TOP_c3_muls : TOP_c3_mulus;
01302 }
01303 #else
01304 if (! MTYPE_is_size_double(mtype))
01305 top = MTYPE_signed(mtype) ? TOP_mult : TOP_multu;
01306 else top = MTYPE_signed(mtype) ? TOP_dmult : TOP_dmultu;
01307 #endif
01308
01309 #if defined(TARG_SL)
01310 TN *zero_tn = Gen_Literal_TN(0, 4);
01311 if (CG_sl2) {
01312 TN* hi_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_cop_creg, 8, 0);
01313 Build_OP(top, result, hi_tn, src1, src2, zero_tn, Zero_TN, zero_tn, ops);
01314 } else {
01315 Build_OP(top, HI_TN, result, src1, src2,zero_tn,ops);
01316 }
01317 #else
01318 Build_OP(top, Hilo_TN(), src1, src2, ops);
01319 Build_OP(TOP_mflo, result, Hilo_TN(), ops);
01320 #endif
01321 }
01322
01323
01324 void
01325 Expand_High_Multiply (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01326 {
01327 TOP top;
01328 FmtAssert(!TN_is_constant(src1),("Expand_High_Multiply: unexpected constant operand"));
01329
01330 #if defined(TARG_SL)
01331 Is_True(!(MTYPE_is_size_double(mtype)), ("Expand_High_Multiply: unsupport 64-bit compute"));
01332 top = MTYPE_signed(mtype) ? TOP_c3_muls : TOP_c3_mulus;
01333 #else
01334 if (!MTYPE_is_size_double(mtype))
01335 top = MTYPE_signed(mtype) ? TOP_mult : TOP_multu;
01336 else top = MTYPE_signed(mtype) ? TOP_dmult : TOP_dmultu;
01337 #endif
01338
01339 if (TN_is_constant(src2))
01340 src2 = Expand_Immediate_Into_Register(src2, MTYPE_is_size_double(mtype), ops);
01341
01342 #if defined(TARG_SL)
01343 TN *lo_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
01344 TN *zero_tn = Gen_Literal_TN(0, 4);
01345 Build_OP(top, HI_TN, lo_tn, src1, src2, zero_tn, ops);
01346 Build_OP(TOP_c3_mvfs, result, HI_TN, zero_tn, ops);
01347 #else
01348 Build_OP(top, Hilo_TN(), src1, src2, ops);
01349 Build_OP(TOP_mfhi, result, Hilo_TN(), ops);
01350 #endif
01351 }
01352
01353
01354 void
01355 Expand_Logical_Not (TN *dest, TN *src, VARIANT variant, OPS *ops)
01356 {
01357
01358 Build_OP (TOP_xori, dest, src, Gen_Literal_TN(1, 4), ops);
01359 }
01360
01361 void
01362 Expand_Logical_And (TN *dest, TN *src1, TN *src2, VARIANT variant, OPS *ops)
01363 {
01364 Build_OP (TOP_and, dest, src1, src2, ops);
01365 }
01366
01367 void
01368 Expand_Logical_Or (TN *dest, TN *src1, TN *src2, VARIANT variant, OPS *ops)
01369 {
01370 Build_OP (TOP_or, dest, src1, src2, ops);
01371 }
01372
01373
01374 void
01375 Expand_Binary_Complement (TN *dest, TN *src, TYPE_ID , OPS *ops)
01376 {
01377 Build_OP(TOP_nor, dest, src, Zero_TN, ops);
01378 }
01379
01380 void
01381 Expand_Binary_And (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01382 {
01383 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
01384 ("Expand_Binary_And: illegal result size\n"));
01385 if (TN_is_constant(src1)) {
01386 INT64 val;
01387 if (TN_has_value(src1)) {
01388 val = TN_value(src1);
01389 if (val == -1) {
01390 Expand_Copy (dest, src2, mtype, ops);
01391 return;
01392 }
01393 }
01394 else FmtAssert(FALSE,("unexpected constant in Expand_Binary_And"));
01395
01396 TOP new_opcode;
01397 if (ISA_LC_Value_In_Class ( val, LC_uimm16))
01398 new_opcode = TOP_andi;
01399 else {
01400 src1 = Expand_Immediate_Into_Register(src1, MTYPE_bit_size(mtype) == 64,
01401 ops);
01402 new_opcode = TOP_and;
01403 }
01404 Build_OP (new_opcode, dest, src2, src1, ops);
01405 }
01406 else if (TN_is_constant(src2)) {
01407
01408 Expand_Binary_And (dest, src2, src1, mtype, ops);
01409 }
01410 else {
01411 Build_OP (TOP_and, dest, src1, src2, ops);
01412 }
01413 }
01414
01415 void
01416 Expand_Binary_Or (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01417 {
01418 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
01419 ("Expand_Binary_Or: illegal dest size\n"));
01420 if (TN_is_constant(src1)) {
01421 INT64 val;
01422 if (TN_has_value(src1)) {
01423 val = TN_value(src1);
01424 if (val == 0) {
01425 Expand_Copy (dest, src2, mtype, ops);
01426 return;
01427 }
01428 }
01429 else FmtAssert(FALSE,("unexpected constant in Expand_Binary_Or"));
01430
01431 TOP new_opcode;
01432 if (ISA_LC_Value_In_Class ( val, LC_uimm16))
01433 new_opcode = TOP_ori;
01434 else {
01435 src1 = Expand_Immediate_Into_Register(src1, MTYPE_bit_size(mtype) == 64,
01436 ops);
01437 new_opcode = TOP_or;
01438 }
01439 Build_OP (new_opcode, dest, src2, src1, ops);
01440 }
01441 else if (TN_is_constant(src2)) {
01442
01443 Expand_Binary_Or (dest, src2, src1, mtype, ops);
01444 }
01445 else {
01446 Build_OP (TOP_or, dest, src1, src2, ops);
01447 }
01448 }
01449
01450 void
01451 Expand_Binary_Xor (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01452 {
01453 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
01454 ("Expand_Binary_Xor: illegal dest size\n"));
01455 if (TN_is_constant(src1)) {
01456 INT64 val;
01457 if (TN_has_value(src1))
01458 val = TN_value(src1);
01459 else FmtAssert(FALSE,("unexpected constant in Expand_Binary_Xor"));
01460 if (val == 0 && src1 == dest)
01461 return;
01462
01463 TOP new_opcode;
01464 if (ISA_LC_Value_In_Class ( val, LC_uimm16))
01465 new_opcode = TOP_xori;
01466 else {
01467 src1 = Expand_Immediate_Into_Register(src1, MTYPE_bit_size(mtype) == 64,
01468 ops);
01469 new_opcode = TOP_xor;
01470 }
01471 Build_OP (new_opcode, dest, src2, src1, ops);
01472 }
01473 else if (TN_is_constant(src2)) {
01474
01475 Expand_Binary_Xor (dest, src2, src1, mtype, ops);
01476 }
01477 else {
01478 Build_OP (TOP_xor, dest, src1, src2, ops);
01479 }
01480 }
01481
01482 void
01483 Expand_Binary_Nor (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01484 {
01485 Build_OP (TOP_nor, dest, src1, src2, ops);
01486 }
01487
01488 void
01489 Expand_Int_Less (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01490 {
01491 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
01492 ("Expand_Int_Less: illegal dest size\n"));
01493 if (TN_is_constant(src2)) {
01494 INT64 val;
01495 if (TN_has_value(src2))
01496 val = TN_value(src2);
01497 else if ( TN_is_symbol(src2) ) {
01498
01499 ST *base;
01500 INT64 val;
01501 Base_Symbol_And_Offset_For_Addressing (TN_var(src2), TN_offset(src2), &base, &val);
01502 }
01503 else FmtAssert(FALSE,("unexpected constant in Expand_Int_Less"));
01504
01505 TOP new_opcode;
01506 if (ISA_LC_Value_In_Class ( val, LC_simm16))
01507 new_opcode = MTYPE_signed(mtype) ? TOP_slti : TOP_sltiu;
01508 else {
01509 src2 = Expand_Immediate_Into_Register(src2, MTYPE_bit_size(mtype) == 64,
01510 ops);
01511 new_opcode = MTYPE_signed(mtype) ? TOP_slt : TOP_sltu;
01512 }
01513 Build_OP (new_opcode, dest, src1, src2, ops);
01514 }
01515 else
01516 Build_OP (MTYPE_signed(mtype) ? TOP_slt : TOP_sltu, dest, src1, src2, ops);
01517 }
01518
01519 void
01520 Expand_Int_Less_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01521 {
01522 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
01523 ("Expand_Int_Less_Equal: illegal dest size\n"));
01524 if (TN_is_constant(src2)) {
01525 INT64 val;
01526 if (TN_has_value(src2))
01527 val = TN_value(src2);
01528 #if 0 // I doubt this case is working (fchow mar-12-03)
01529 else if ( TN_is_symbol(src2) ) {
01530
01531 ST *base;
01532 INT64 val;
01533 Base_Symbol_And_Offset_For_Addressing (TN_var(src2), TN_offset(src2), &base, &val);
01534 }
01535 #endif
01536 else FmtAssert(FALSE,("unexpected constant in Expand_Int_Less_Equal"));
01537
01538 if (ISA_LC_Value_In_Class ( val+1, LC_simm16)) {
01539 Build_OP(MTYPE_signed(mtype) ? TOP_slti : TOP_sltiu, dest, src1,
01540 Gen_Literal_TN(val+1, 4), ops);
01541 }
01542 else {
01543 INT size = MTYPE_byte_size(mtype);
01544 src2 = Expand_Immediate_Into_Register(Gen_Literal_TN(val+1, size),
01545 size == 8, ops);
01546 Build_OP(MTYPE_signed(mtype) ? TOP_slt : TOP_sltu, dest, src1, src2, ops);
01547 }
01548 }
01549 else {
01550 TN *tmp = Build_TN_Of_Mtype(mtype);
01551 Build_OP (MTYPE_signed(mtype) ? TOP_slt : TOP_sltu, tmp, src2, src1, ops);
01552 Build_OP (TOP_xori, dest, tmp, Gen_Literal_TN(1, 4), ops);
01553 }
01554 }
01555
01556 void
01557 Expand_Int_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01558 {
01559 TN *tmp_tn;
01560 if ((TN_size(dest) == MTYPE_byte_size(mtype)) &&
01561 !TN_is_dedicated(dest))
01562 tmp_tn = dest;
01563 else tmp_tn = Gen_Typed_Register_TN(mtype, MTYPE_byte_size(mtype));
01564 Expand_Binary_Xor(tmp_tn, src1, src2, mtype, ops);
01565 Build_OP (TOP_sltiu, dest, tmp_tn, Gen_Literal_TN(1, 4), ops);
01566 }
01567
01568 void
01569 Expand_Int_Not_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01570 {
01571 TN *tmp_tn;
01572 if ((TN_size(dest) == MTYPE_byte_size(mtype)) &&
01573 !TN_is_dedicated(dest))
01574 tmp_tn = dest;
01575 else tmp_tn = Gen_Typed_Register_TN(mtype, MTYPE_byte_size(mtype));
01576 Expand_Binary_Xor(tmp_tn, src1, src2, mtype, ops);
01577 Build_OP (TOP_sltu, dest, Zero_TN, tmp_tn, ops);
01578 }
01579
01580 void
01581 Expand_Int_Greater_Equal (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01582 {
01583 TN *tmp_tn;
01584 if ((TN_size(dest) == MTYPE_byte_size(mtype)) &&
01585 !TN_is_dedicated(dest))
01586 tmp_tn = dest;
01587 else tmp_tn = Gen_Typed_Register_TN(mtype, MTYPE_byte_size(mtype));
01588 Expand_Int_Less(tmp_tn, src1, src2, mtype, ops);
01589 Build_OP (TOP_xori, dest, tmp_tn, Gen_Literal_TN(1, 4), ops);
01590 }
01591
01592 void
01593 Expand_Int_Greater (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01594 {
01595 FmtAssert ((MTYPE_bit_size(mtype) == 32 || MTYPE_bit_size(mtype) == 64),
01596 ("Expand_Int_Greater: illegal dest size\n"));
01597 if (TN_is_constant(src1))
01598 src1 = Expand_Immediate_Into_Register(src1, MTYPE_bit_size(mtype)==64, ops);
01599 if (TN_is_constant(src2))
01600 src2 = Expand_Immediate_Into_Register(src2, MTYPE_bit_size(mtype)==64, ops);
01601 Build_OP (MTYPE_signed(mtype) ? TOP_slt : TOP_sltu, dest, src2, src1, ops);
01602 }
01603
01604 static void
01605 Expand_Bool_Comparison (BOOL equals, TN *dest, TN *src1, TN *src2, OPS *ops)
01606 { FmtAssert(FALSE,("Unimplemented")); }
01607
01608 void
01609 Expand_Bool_Equal (TN *dest, TN *src1, TN *src2, OPS *ops)
01610 { FmtAssert(FALSE,("Unimplemented")); }
01611
01612 void
01613 Expand_Bool_Not_Equal (TN *dest, TN *src1, TN *src2, OPS *ops)
01614 { FmtAssert(FALSE,("Unimplemented")); }
01615
01616 void
01617 Expand_Bool_To_Int (TN *dest, TN *src, TYPE_ID rtype, OPS *ops)
01618 { FmtAssert(FALSE,("Unimplemented")); }
01619
01620 typedef enum {
01621 ROUND_USER,
01622 ROUND_NEAREST,
01623 ROUND_CHOP,
01624 ROUND_NEG_INF,
01625 ROUND_PLUS_INF
01626 } ROUND_MODE;
01627
01628
01629 static void
01630 Expand_Float_To_Int (ROUND_MODE rm, TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01631 {
01632 TOP top;
01633 BOOL int_64bit = MTYPE_byte_size(imtype) == 8;
01634 if (fmtype == MTYPE_F4) {
01635 if (int_64bit || !(MTYPE_is_signed(imtype))) {
01636 switch (rm) {
01637 case ROUND_USER: top = TOP_cvt_l_s; break;
01638 case ROUND_NEAREST: top = TOP_round_l_s; break;
01639 case ROUND_CHOP: top = TOP_trunc_l_s; break;
01640 case ROUND_NEG_INF: top = TOP_floor_l_s; break;
01641 case ROUND_PLUS_INF: top = TOP_ceil_l_s; break;
01642 default: FmtAssert(FALSE,("Unimplemented rounding mode"));
01643 }
01644 }
01645 else {
01646 switch (rm) {
01647 case ROUND_USER: top = TOP_cvt_w_s; break;
01648 case ROUND_NEAREST: top = TOP_round_w_s; break;
01649 case ROUND_CHOP: top = TOP_trunc_w_s; break;
01650 case ROUND_NEG_INF: top = TOP_floor_w_s; break;
01651 case ROUND_PLUS_INF: top = TOP_ceil_w_s; break;
01652 default: FmtAssert(FALSE,("Unimplemented rounding mode"));
01653 }
01654 }
01655 }
01656 else if (fmtype == MTYPE_F8) {
01657 if (int_64bit || !(MTYPE_is_signed(imtype))) {
01658 switch (rm) {
01659 case ROUND_USER: top = TOP_cvt_l_d; break;
01660 case ROUND_NEAREST: top = TOP_round_l_d; break;
01661 case ROUND_CHOP: top = TOP_trunc_l_d; break;
01662 case ROUND_NEG_INF: top = TOP_floor_l_d; break;
01663 case ROUND_PLUS_INF: top = TOP_ceil_l_d; break;
01664 default: FmtAssert(FALSE,("Unimplemented rounding mode"));
01665 }
01666 }
01667 else {
01668 switch (rm) {
01669 case ROUND_USER: top = TOP_cvt_w_d; break;
01670 case ROUND_NEAREST: top = TOP_round_w_d; break;
01671 case ROUND_CHOP: top = TOP_trunc_w_d; break;
01672 case ROUND_NEG_INF: top = TOP_floor_w_d; break;
01673 case ROUND_PLUS_INF: top = TOP_ceil_w_d; break;
01674 default: FmtAssert(FALSE,("Unimplemented rounding mode"));
01675 }
01676 }
01677 }
01678 else FmtAssert(FALSE,("unsupported float size in Expand_Float_To_Int"));
01679 if (imtype == fmtype)
01680 return;
01681 TN *tmp = Build_TN_Of_Mtype (fmtype);
01682 Build_OP(top, tmp, src, ops);
01683 Build_OP(int_64bit ? TOP_dmfc1 : TOP_mfc1, dest, tmp, ops);
01684 }
01685
01686 void
01687 Expand_Float_To_Int_Cvt (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01688 {
01689 Expand_Float_To_Int (ROUND_USER, dest, src, imtype, fmtype, ops);
01690 }
01691
01692 void
01693 Expand_Float_To_Int_Round (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01694 {
01695 Expand_Float_To_Int (ROUND_NEAREST, dest, src, imtype, fmtype, ops);
01696 }
01697
01698 void
01699 Expand_Float_To_Int_Trunc (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01700 {
01701 #if !defined(TARG_SL)
01702 Expand_Float_To_Int (ROUND_CHOP, dest, src, imtype, fmtype, ops);
01703 #else
01704 TN* tmp = Build_TN_Of_Mtype(MTYPE_I4);
01705 TN* tmp2 = Build_TN_Of_Mtype(MTYPE_I4);
01706 Build_OP(TOP_cfc1, tmp2, ops);
01707 Build_OP(TOP_ori, tmp, tmp2, Gen_Literal_TN(0x3, 4), ops);
01708 Build_OP(TOP_xori, tmp, tmp, Gen_Literal_TN(0x2, 4), ops);
01709 Build_OP(TOP_ctc1, tmp,ops);
01710 Build_OP(fmtype == MTYPE_F4 ? TOP_cvt_w_s : TOP_cvt_w_d, src, src, ops);
01711 Build_OP(TOP_ctc1, tmp2, ops);
01712 Build_OP(TOP_mfc1, dest, src, ops);
01713 #endif
01714 }
01715
01716
01717 void
01718 Expand_Float_To_Int_Floor (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01719 {
01720 Expand_Float_To_Int (ROUND_NEG_INF, dest, src, imtype, fmtype, ops);
01721 }
01722
01723 void
01724 Expand_Float_To_Int_Ceil (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01725 {
01726 Expand_Float_To_Int (ROUND_PLUS_INF, dest, src, imtype, fmtype, ops);
01727 }
01728
01729 void
01730 Expand_Float_To_Float (TN *dest, TN *src, TYPE_ID rtype, TYPE_ID desc, OPS *ops)
01731 {
01732 TOP top = (rtype == MTYPE_F8) ? TOP_cvt_d_s : TOP_cvt_s_d;
01733 Build_OP(top, dest, src, ops);
01734 }
01735
01736
01737 void
01738 Expand_Int_To_Float (TN *dest, TN *src, TYPE_ID imtype, TYPE_ID fmtype, OPS *ops)
01739 {
01740 TOP top;
01741 BOOL int_64bit = MTYPE_byte_size(imtype) == 8;
01742 TN *tmp = Build_TN_Of_Mtype(fmtype);
01743 Build_OP(int_64bit ? TOP_dmtc1 : TOP_mtc1, tmp, src, ops);
01744 if (fmtype == MTYPE_F4) {
01745
01746 top = (MTYPE_is_signed(imtype)? TOP_cvt_s_w: TOP_cvt_s_l);
01747 if (MTYPE_is_size_double(imtype))
01748 top = TOP_cvt_s_l;
01749 }
01750 else if (fmtype == MTYPE_F8) {
01751
01752 top = (MTYPE_is_signed(imtype)? TOP_cvt_d_w: TOP_cvt_d_l);
01753 if (MTYPE_is_size_double(imtype))
01754 top = TOP_cvt_d_l;
01755 }
01756 else FmtAssert(FALSE,("unsupported float size in Expand_Int_To_Float"));
01757 Build_OP(top, dest, tmp, ops);
01758 }
01759
01760
01761 static BOOL
01762 Optimize_Select (
01763 TOP cmp,
01764 TN *cond1,
01765 TN *cond2,
01766 TN *dest,
01767 TN *dest2,
01768 TN *src1,
01769 TN *src2,
01770 BOOL is_float,
01771 OPS *ops)
01772 {
01773 return FALSE;
01774 }
01775
01776
01777
01778 static void
01779 Expand_Compare_And_Select (
01780 TOP cmp,
01781 TN *cond1,
01782 TN *cond2,
01783 TN *dest,
01784 TN *opposite_dest,
01785 TN *true_tn,
01786 TN *false_tn,
01787 BOOL is_float,
01788 OPS *ops)
01789 { FmtAssert(FALSE,("Unimplemented")); }
01790
01791
01792 #ifdef TARG_SL
01793 void
01794 Expand_Select (
01795 TN *dest_tn,
01796 TN *cond_tn,
01797 TN *true_tn,
01798 TN *false_tn,
01799 TYPE_ID mtype,
01800 BOOL float_cond,
01801 OPS *ops)
01802 {
01803 const BOOL is_float = MTYPE_is_float(mtype);
01804 int unsignedflag = (mtype == MTYPE_U4) ? 1 : 0;
01805 Is_True((mtype == MTYPE_U4 || mtype==MTYPE_I4) , ("mtype must be MTYPE_I4 or MTYPE_U4" ));
01806
01807 if (TN_register_class(cond_tn) == ISA_REGISTER_CLASS_fcc) {
01808 if (is_float) {
01809 Build_OP(MTYPE_is_size_double(mtype)?TOP_movt_d:TOP_movt_s,
01810 dest_tn, true_tn, cond_tn, ops);
01811 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01812 Build_OP(MTYPE_is_size_double(mtype)?TOP_movf_d:TOP_movf_s,
01813 dest_tn, false_tn, cond_tn, ops);
01814 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01815 } else {
01816 Build_OP(TOP_movt, dest_tn, true_tn, cond_tn, ops);
01817 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01818 Build_OP(TOP_movf, dest_tn, false_tn, cond_tn, ops);
01819 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01820 }
01821 } else if (TN_register_class(cond_tn) == ISA_REGISTER_CLASS_integer) {
01822 if (is_float) {
01823 Build_OP(MTYPE_is_size_double(mtype)?TOP_movn_d:TOP_movn_s,
01824 dest_tn, true_tn, cond_tn, ops);
01825 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01826 Build_OP(MTYPE_is_size_double(mtype)?TOP_movz_d:TOP_movz_s,
01827 dest_tn, false_tn, cond_tn, ops);
01828 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01829 } else {
01830 if (tns_are_equals(true_tn, false_tn)) {
01831 Build_OP(TOP_addu, dest_tn, true_tn, Zero_TN, ops);
01832 DevWarn("Conditional move:: Expand_Select(1 instructions -copy) ");
01833 } else if (tns_are_equals(Zero_TN, true_tn)) {
01834 Build_MC_OP(TOP_mc_zc_eq, dest_tn, cond_tn, false_tn,unsignedflag, ops, OP_ALWAYS_UNC_DEF);
01835 } else if (tns_are_equals(Zero_TN, false_tn)) {
01836 Build_MC_OP(TOP_mc_zc_ne, dest_tn, cond_tn, true_tn, unsignedflag, ops, OP_ALWAYS_UNC_DEF);
01837 } else if (tns_are_equals(dest_tn, false_tn)) {
01838 Build_MC_OP(TOP_mc_z_ne, dest_tn, cond_tn, true_tn, unsignedflag, ops, OP_ALWAYS_COND_DEF);
01839 } else if (tns_are_equals(dest_tn, true_tn)) {
01840 Build_MC_OP(TOP_mc_z_eq, dest_tn, cond_tn, false_tn, unsignedflag, ops, OP_ALWAYS_COND_DEF);
01841 } else {
01842 Exp_2inst_MC_Zero (TOP_mc_z_ne, dest_tn, true_tn, false_tn, cond_tn, unsignedflag, ops);
01843 DevWarn("Conditional move:: Expand_Select(2 instructions) ");
01844 }
01845 }
01846 } else if (TN_register_class(cond_tn) == ISA_REGISTER_CLASS_float) {
01847 TN *tmp_tn = Gen_Typed_Register_TN(MTYPE_I4, 4);
01848 Build_OP(TOP_mfc1, tmp_tn, cond_tn, ops);
01849 if (is_float) {
01850 Build_OP(MTYPE_is_size_double(mtype)?TOP_movn_d:TOP_movn_s,
01851 dest_tn, true_tn, tmp_tn, ops);
01852 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01853 Build_OP(MTYPE_is_size_double(mtype)?TOP_movz_d:TOP_movz_s,
01854 dest_tn, false_tn, tmp_tn, ops);
01855 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01856 } else {
01857 DevWarn("Conditional move:: Expand_Select (float) ");
01858 if (tns_are_equals(true_tn, false_tn)) {
01859 Build_OP(TOP_addu, dest_tn, true_tn, Zero_TN, ops);
01860 DevWarn("Conditional move:: Expand_Select(float: 1 instructions -copy) ");
01861 } else if (tns_are_equals(Zero_TN, true_tn)) {
01862 Build_MC_OP(TOP_mc_zc_eq, dest_tn, tmp_tn, false_tn, unsignedflag, ops, OP_ALWAYS_UNC_DEF);
01863 } else if (tns_are_equals(Zero_TN, false_tn)) {
01864 Build_MC_OP(TOP_mc_zc_ne, dest_tn, tmp_tn, true_tn, unsignedflag, ops, OP_ALWAYS_UNC_DEF);
01865 } else {
01866 Exp_2inst_MC_Zero (TOP_mc_z_ne, dest_tn, true_tn, false_tn, tmp_tn,unsignedflag, ops);
01867 DevWarn("Conditional move:: Expand_Select(float: 2 instructions) ");
01868 }
01869 }
01870 } else {
01871 FmtAssert(FALSE, ("UNIMPLEMENTED"));
01872 }
01873 }
01874 #else
01875
01876 void
01877 Expand_Select (
01878 TN *dest_tn,
01879 TN *cond_tn,
01880 TN *true_tn,
01881 TN *false_tn,
01882 TYPE_ID mtype,
01883 BOOL float_cond,
01884 OPS *ops)
01885 {
01886 const BOOL is_float = MTYPE_is_float(mtype);
01887 if (TN_register_class(cond_tn) == ISA_REGISTER_CLASS_fcc) {
01888 if (is_float) {
01889 Build_OP(MTYPE_is_size_double(mtype)?TOP_movt_d:TOP_movt_s,
01890 dest_tn, true_tn, cond_tn, ops);
01891 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01892 Build_OP(MTYPE_is_size_double(mtype)?TOP_movf_d:TOP_movf_s,
01893 dest_tn, false_tn, cond_tn, ops);
01894 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01895 } else {
01896 Build_OP(TOP_movt, dest_tn, true_tn, cond_tn, ops);
01897 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01898 Build_OP(TOP_movf, dest_tn, false_tn, cond_tn, ops);
01899 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01900 }
01901 } else if (TN_register_class(cond_tn) == ISA_REGISTER_CLASS_integer) {
01902 if (is_float) {
01903 Build_OP(MTYPE_is_size_double(mtype)?TOP_movn_d:TOP_movn_s,
01904 dest_tn, true_tn, cond_tn, ops);
01905 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01906 Build_OP(MTYPE_is_size_double(mtype)?TOP_movz_d:TOP_movz_s,
01907 dest_tn, false_tn, cond_tn, ops);
01908 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01909 } else {
01910 Build_OP(TOP_movn, dest_tn, true_tn, cond_tn, ops);
01911 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01912 Build_OP(TOP_movz, dest_tn, false_tn, cond_tn, ops);
01913 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01914 }
01915 } else if (TN_register_class(cond_tn) == ISA_REGISTER_CLASS_float) {
01916 TN *tmp_tn = Gen_Typed_Register_TN(MTYPE_I4, 4);
01917 Build_OP(TOP_mfc1, tmp_tn, cond_tn, ops);
01918 if (is_float) {
01919 Build_OP(MTYPE_is_size_double(mtype)?TOP_movn_d:TOP_movn_s,
01920 dest_tn, true_tn, tmp_tn, ops);
01921 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01922 Build_OP(MTYPE_is_size_double(mtype)?TOP_movz_d:TOP_movz_s,
01923 dest_tn, false_tn, tmp_tn, ops);
01924 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01925 } else {
01926 Build_OP(TOP_movn, dest_tn, true_tn, tmp_tn, ops);
01927 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01928 Build_OP(TOP_movz, dest_tn, false_tn, tmp_tn, ops);
01929 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01930 }
01931 } else {
01932 FmtAssert(FALSE, ("UNIMPLEMENTED"));
01933 }
01934 }
01935 #endif
01936
01937 void
01938 Expand_Min (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01939 {
01940 BOOL is_signed = MTYPE_is_signed(mtype);
01941 if (!MTYPE_is_float(mtype)) {
01942 TN *tmp_tn = Gen_Typed_Register_TN(MTYPE_I4, 4);
01943 if (src1 == dest) {
01944 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src1, src2, ops);
01945 Build_OP(TOP_movz, dest, src2, tmp_tn, ops);
01946 }
01947 else if (src2 == dest) {
01948 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src2, src1, ops);
01949 Build_OP(TOP_movz, dest, src1, tmp_tn, ops);
01950 }
01951 else {
01952 Build_OP(TOP_or, dest, src1, Zero_TN, ops);
01953 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src1, src2, ops);
01954 Build_OP(TOP_movz, dest, src2, tmp_tn, ops);
01955 }
01956 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01957 } else {
01958 TN *tmp_fcc = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 1);
01959 if (src1 == dest) {
01960 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
01961 tmp_fcc, src2, src1, ops);
01962 Build_OP(MTYPE_is_size_double(mtype)? TOP_movt_d: TOP_movt_s,
01963 dest, src2, tmp_fcc, ops);
01964 }
01965 else if (src2 == dest) {
01966 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
01967 tmp_fcc, src1, src2, ops);
01968 Build_OP(MTYPE_is_size_double(mtype)? TOP_movt_d: TOP_movt_s,
01969 dest, src1, tmp_fcc, ops);
01970 }
01971 else {
01972 Build_OP(MTYPE_is_size_double(mtype)? TOP_mov_d: TOP_mov_s,
01973 dest, src2, ops);
01974 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
01975 tmp_fcc, src1, src2, ops);
01976 Build_OP(MTYPE_is_size_double(mtype)? TOP_movt_d: TOP_movt_s,
01977 dest, src1, tmp_fcc, ops);
01978 }
01979 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
01980 }
01981 }
01982
01983 void
01984 Expand_Max (TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01985 {
01986 BOOL is_signed = MTYPE_is_signed(mtype);
01987 if (!MTYPE_is_float(mtype)) {
01988 TN *tmp_tn = Gen_Typed_Register_TN(MTYPE_I4, 4);
01989 if (src1 == dest) {
01990 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src2, src1, ops);
01991 Build_OP(TOP_movz, dest, src2, tmp_tn, ops);
01992 }
01993 else if (src2 == dest) {
01994 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src1, src2, ops);
01995 Build_OP(TOP_movz, dest, src1, tmp_tn, ops);
01996 }
01997 else {
01998 Build_OP(TOP_or, dest, src2, Zero_TN, ops);
01999 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src1, src2, ops);
02000 Build_OP(TOP_movz, dest, src1, tmp_tn, ops);
02001 }
02002 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
02003 } else {
02004 TN *tmp_fcc = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 1);
02005 if (src1 == dest) {
02006 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
02007 tmp_fcc, src1, src2, ops);
02008 Build_OP(MTYPE_is_size_double(mtype)? TOP_movt_d: TOP_movt_s,
02009 dest, src2, tmp_fcc, ops);
02010 }
02011 else if (src2 == dest) {
02012 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
02013 tmp_fcc, src2, src1, ops);
02014 Build_OP(MTYPE_is_size_double(mtype)? TOP_movt_d: TOP_movt_s,
02015 dest, src1, tmp_fcc, ops);
02016 }
02017 else {
02018 Build_OP(MTYPE_is_size_double(mtype)? TOP_mov_d: TOP_mov_s,
02019 dest, src1, ops);
02020 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
02021 tmp_fcc, src1, src2, ops);
02022 Build_OP(MTYPE_is_size_double(mtype)? TOP_movt_d: TOP_movt_s,
02023 dest, src2, tmp_fcc, ops);
02024 }
02025 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
02026 }
02027 }
02028
02029 void
02030 Expand_MinMax (TN *dest, TN *dest2, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02031 {
02032 BOOL is_signed = MTYPE_is_signed(mtype);
02033 FmtAssert(dest != src1 && dest2 != src1 && dest != src2 && dest2 != src2,
02034 ("Expand_MinMax: dest TN cannot be also src TN"));
02035 if (!MTYPE_is_float(mtype)) {
02036 TN *tmp_tn = Gen_Typed_Register_TN(MTYPE_I4, 4);
02037 Build_OP(TOP_or, dest, src1, Zero_TN, ops);
02038 Build_OP(TOP_or, dest2, src2, Zero_TN, ops);
02039 Build_OP(is_signed?TOP_slt:TOP_sltu, tmp_tn, src1, src2, ops);
02040 Build_OP(TOP_movz, dest, src2, tmp_tn, ops);
02041 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
02042 Build_OP(TOP_movz, dest2, src1, tmp_tn, ops);
02043 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
02044 } else {
02045 TN *tmp_fcc = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 1);
02046 Build_OP(MTYPE_is_size_double(mtype)? TOP_mov_d: TOP_mov_s,
02047 dest, src1, ops);
02048 Build_OP(MTYPE_is_size_double(mtype)? TOP_mov_d: TOP_mov_s,
02049 dest2, src2, ops);
02050 Build_OP(MTYPE_is_size_double(mtype)? TOP_c_lt_d: TOP_c_lt_s,
02051 tmp_fcc, src1, src2, ops);
02052 Build_OP(MTYPE_is_size_double(mtype)? TOP_movf_d: TOP_movf_s,
02053 dest, src2, tmp_fcc, ops);
02054 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
02055 Build_OP(MTYPE_is_size_double(mtype)? TOP_movf_d: TOP_movf_s,
02056 dest2, src1, tmp_fcc, ops);
02057 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
02058 }
02059 }
02060
02061
02062 extern BOOL
02063 Check_Select_Expansion (OPCODE compare)
02064 {
02065
02066
02067
02068
02069 return FALSE;
02070 }
02071
02072 extern void
02073 Exp_Select_And_Condition (
02074 OPCODE select, TN *result, TN *true_tn, TN *false_tn,
02075 OPCODE compare, TN *cmp_kid1, TN *cmp_kid2, VARIANT variant, OPS *ops)
02076 {
02077 TOP cmp1, cmp2;
02078
02079 if (Trace_Exp) {
02080 fprintf(TFile, "expand %s: ", OPCODE_name(select));
02081 if (result) Print_TN(result,FALSE);
02082 fprintf(TFile, " :- (");
02083 if (cmp_kid1) Print_TN(cmp_kid1,FALSE);
02084 fprintf(TFile, " ");
02085 fprintf(TFile, OPCODE_name(compare));
02086 fprintf(TFile, " ");
02087 if (cmp_kid2) Print_TN(cmp_kid2,FALSE);
02088 fprintf(TFile, ") ? ");
02089 if (true_tn) Print_TN(true_tn,FALSE);
02090 fprintf(TFile, " : ");
02091 if (false_tn) Print_TN(false_tn,FALSE);
02092 fprintf(TFile, " ");
02093 if (variant) fprintf(TFile, "(0x%llx)", (INT64)variant);
02094 fprintf(TFile, "\n");
02095 }
02096
02097 TYPE_ID desc = OPCODE_desc(compare);
02098 OPERATOR compare_opr = OPCODE_operator(compare);
02099 TN *p;
02100 OPS new_ops;
02101 OPS_Init(&new_ops);
02102 if (MTYPE_is_float(desc))
02103 p = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 1);
02104 else p = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
02105
02106 if (compare_opr == OPR_NE) {
02107 TN *tmp = true_tn;
02108 true_tn = false_tn;
02109 false_tn = tmp;
02110 compare_opr = OPR_EQ;
02111 }
02112
02113 switch(compare_opr) {
02114 case OPR_LT:
02115 if (MTYPE_is_float(desc))
02116 Expand_Float_Less (p, cmp_kid1, cmp_kid2, variant, desc, &new_ops);
02117 else
02118 Expand_Int_Less (p, cmp_kid1, cmp_kid2, desc, &new_ops);
02119 break;
02120 case OPR_LE:
02121 if (MTYPE_is_float(desc))
02122 Expand_Float_Less_Equal (p, cmp_kid1, cmp_kid2, variant, desc, &new_ops);
02123 else
02124 Expand_Int_Less_Equal (p, cmp_kid1, cmp_kid2, desc, &new_ops);
02125 break;
02126 case OPR_EQ:
02127 if (MTYPE_is_float(desc))
02128 Expand_Float_Equal (p, cmp_kid1, cmp_kid2, variant, desc, &new_ops);
02129 else if (desc == MTYPE_B)
02130 Expand_Bool_Equal (p, cmp_kid1, cmp_kid2, &new_ops);
02131 else
02132 Expand_Int_Equal (p, cmp_kid1, cmp_kid2, desc, &new_ops);
02133 break;
02134 #if 0 // this case avoided by above transformation
02135 case OPR_NE:
02136 if (MTYPE_is_float(desc))
02137 Expand_Float_Not_Equal (p, cmp_kid1, cmp_kid2, variant, desc, &new_ops);
02138 else if (desc == MTYPE_B)
02139 Expand_Bool_Not_Equal (p, cmp_kid1, cmp_kid2, &new_ops);
02140 else
02141 Expand_Int_Not_Equal (p, cmp_kid1, cmp_kid2, desc, &new_ops);
02142 break;
02143 #endif
02144 case OPR_GE:
02145 if (MTYPE_is_float(desc))
02146 Expand_Float_Greater_Equal (p, cmp_kid1, cmp_kid2, variant, desc, &new_ops);
02147 else
02148 Expand_Int_Greater_Equal (p, cmp_kid1, cmp_kid2, desc, &new_ops);
02149 break;
02150 case OPR_GT:
02151 if (MTYPE_is_float(desc))
02152 Expand_Float_Greater (p, cmp_kid1, cmp_kid2, variant, desc, &new_ops);
02153 else
02154 Expand_Int_Greater (p, cmp_kid1, cmp_kid2, desc, &new_ops);
02155 break;
02156 default:
02157 FmtAssert(FALSE, ("Unknown opcode"));
02158 }
02159
02160 if (result != true_tn && result != false_tn) {
02161 if (MTYPE_is_float(OPCODE_rtype(select))) {
02162 Build_OP (MTYPE_is_size_double(OPCODE_rtype(select))?TOP_mov_d:TOP_mov_s,
02163 result, true_tn, &new_ops);
02164 } else {
02165 Build_OP (TOP_or, result, Zero_TN, true_tn, &new_ops);
02166 }
02167 }
02168
02169 if (MTYPE_is_float(OPCODE_rtype(select))) {
02170 if (result != false_tn) {
02171 if (MTYPE_is_float(desc))
02172 Build_OP (MTYPE_is_size_double(OPCODE_rtype(select))?TOP_movf_d:TOP_movf_s,
02173 result, false_tn, p, &new_ops);
02174 else Build_OP (MTYPE_is_size_double(OPCODE_rtype(select))?TOP_movz_d:TOP_movz_s,
02175 result, false_tn, p, &new_ops);
02176 } else {
02177 if (MTYPE_is_float(desc))
02178 Build_OP (MTYPE_is_size_double(OPCODE_rtype(select))?TOP_movt_d:TOP_movt_s,
02179 result, true_tn, p, &new_ops);
02180 else Build_OP (MTYPE_is_size_double(OPCODE_rtype(select))?TOP_movn_d:TOP_movn_s,
02181 result, true_tn, p, &new_ops);
02182 }
02183 } else {
02184 if (result != false_tn) {
02185 if (MTYPE_is_float(desc))
02186 Build_OP (TOP_movf, result, false_tn, p, &new_ops);
02187 else Build_OP (TOP_movz, result, false_tn, p, &new_ops);
02188 } else {
02189 if (MTYPE_is_float(desc))
02190 Build_OP (TOP_movt, result, true_tn, p, &new_ops);
02191 else Build_OP (TOP_movn, result, true_tn, p, &new_ops);
02192 }
02193 }
02194 Set_OP_cond_def_kind(OPS_last(&new_ops), OP_ALWAYS_COND_DEF);
02195 if (Trace_Exp) {
02196 OP *op;
02197 FOR_ALL_OPS_OPs (&new_ops, op) {
02198 fprintf(TFile, " into "); Print_OP (op);
02199 }
02200 }
02201 OPS_Append_Ops(ops, &new_ops);
02202 }
02203
02204
02205
02206
02207 #define RESET_COND_DEF_LAST(ops) Set_OP_cond_def_kind(OPS_last(ops),OP_ALWAYS_UNC_DEF)
02208
02209 static void
02210 Expand_SGI_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
02211 {
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245 }
02246
02247 static void
02248 Expand_Intel_F10_Sqrt(TN *result, TN *src, OPS *ops)
02249 { FmtAssert(FALSE,("Unimplemented")); }
02250
02251
02252 static void
02253 Expand_Intel_Max_Thr_F8_Sqrt(TN *result, TN *src, OPS *ops)
02254 { FmtAssert(FALSE,("Unimplemented")); }
02255
02256
02257 static void
02258 Expand_Intel_Max_Thr_F4_Sqrt(TN *result, TN *src, OPS *ops)
02259 { FmtAssert(FALSE,("Unimplemented")); }
02260
02261
02262 static void
02263 Expand_Intel_Min_Lat_F8_Sqrt(TN *result, TN *src, OPS *ops)
02264 { FmtAssert(FALSE,("Unimplemented")); }
02265
02266
02267 static void
02268 Expand_Intel_Min_Lat_F4_Sqrt(TN *result, TN *src, OPS *ops)
02269 { FmtAssert(FALSE,("Unimplemented")); }
02270
02271
02272 static void
02273 Expand_Intel_Max_Thr_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
02274 {
02275 switch (mtype) {
02276 case MTYPE_F4:
02277 Expand_Intel_Max_Thr_F4_Sqrt(result, src, ops);
02278 break;
02279 case MTYPE_F8:
02280 Expand_Intel_Max_Thr_F8_Sqrt(result, src, ops);
02281 break;
02282 case MTYPE_F10:
02283 Expand_Intel_F10_Sqrt(result, src, ops);
02284 break;
02285 default:
02286 FmtAssert(FALSE, ("Bad type in Expand_Intel_Max_Thr_Sqrt"));
02287
02288 }
02289 }
02290
02291
02292 static void
02293 Expand_Intel_Min_Lat_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
02294 {
02295 switch (mtype) {
02296 case MTYPE_F4:
02297 Expand_Intel_Min_Lat_F4_Sqrt(result, src, ops);
02298 break;
02299 case MTYPE_F8:
02300 Expand_Intel_Min_Lat_F8_Sqrt(result, src, ops);
02301 break;
02302 case MTYPE_F10:
02303 Expand_Intel_F10_Sqrt(result, src, ops);
02304 break;
02305 default:
02306 FmtAssert(FALSE, ("Bad type in Expand_Intel_Min_Lat_Sqrt"));
02307
02308 }
02309 }
02310
02311
02312 void
02313 Expand_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
02314 {
02315 FmtAssert(TN_register_class(result) == ISA_REGISTER_CLASS_float &&
02316 TN_register_class(src) == ISA_REGISTER_CLASS_float,
02317 ("Unimplemented sqrt for integer src/dest"));
02318 Build_OP(MTYPE_is_size_double(mtype)?TOP_sqrt_d:TOP_sqrt_s,
02319 result, src, ops);
02320 }
02321
02322
02323 static void
02324 Expand_Float_Compares(TOP cmp_opcode, TN *dest, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02325 {
02326 if (TN_register_class(dest) == ISA_REGISTER_CLASS_fcc) {
02327 FmtAssert(cmp_opcode != TOP_c_neq_d && cmp_opcode != TOP_c_neq_s,
02328 ("Expand_Float_Compares: should not use c_neq_[sd] which is not supported by assembler"));
02329 Build_OP(cmp_opcode, dest, src1, src2, ops);
02330 } else {
02331 FmtAssert(TN_register_class(dest) == ISA_REGISTER_CLASS_integer,
02332 ("Expand_Float_Compares: result must be fcc or integer"));
02333 TN *tmp_fcc = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 1);
02334 Build_OP(MTYPE_is_size_double(mtype)?TOP_daddiu:TOP_addiu,
02335 dest, Zero_TN, Gen_Literal_TN(1, 4), ops);
02336 if (cmp_opcode == TOP_c_neq_d || cmp_opcode == TOP_c_neq_s) {
02337 Build_OP(cmp_opcode == TOP_c_neq_d ? TOP_c_eq_d : TOP_c_eq_s,
02338 tmp_fcc, src1, src2, ops);
02339 Build_OP(TOP_movt, dest, Zero_TN, tmp_fcc, ops);
02340 }
02341 else {
02342 Build_OP(cmp_opcode, tmp_fcc, src1, src2, ops);
02343 Build_OP(TOP_movf, dest, Zero_TN, tmp_fcc, ops);
02344 }
02345 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
02346 }
02347 }
02348
02349 void
02350 Expand_Float_Less (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
02351 {
02352 #if defined(TARG_SL)
02353 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_lt_d:TOP_c_olt_s,
02354 #else
02355 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_lt_d:TOP_c_lt_s,
02356 #endif
02357 dest, src1, src2, mtype, ops);
02358 }
02359
02360 void
02361 Expand_Float_Greater (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
02362 {
02363 #if defined(TARG_SL)
02364 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_lt_d:TOP_c_olt_s,
02365 #else
02366 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_lt_d:TOP_c_lt_s,
02367 #endif
02368 dest, src2, src1, mtype, ops);
02369 }
02370
02371 void
02372 Expand_Float_Less_Equal (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
02373 {
02374 #if defined(TARG_SL)
02375 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_le_d:TOP_c_ole_s,
02376 #else
02377 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_le_d:TOP_c_le_s,
02378 #endif
02379 dest, src1, src2, mtype, ops);
02380 }
02381
02382 void
02383 Expand_Float_Greater_Equal (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
02384 {
02385 #if defined(TARG_SL)
02386 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_le_d:TOP_c_ole_s,
02387 #else
02388 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_le_d:TOP_c_le_s,
02389 #endif
02390 dest, src2, src1, mtype, ops);
02391 }
02392
02393 void
02394 Expand_Float_Equal (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
02395 {
02396 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_eq_d:TOP_c_eq_s,
02397 dest, src1, src2, mtype, ops);
02398 }
02399
02400 void
02401 Expand_Float_Not_Equal (TN *dest, TN *src1, TN *src2, VARIANT variant, TYPE_ID mtype, OPS *ops)
02402 {
02403 Expand_Float_Compares(MTYPE_is_size_double(mtype)?TOP_c_neq_d:TOP_c_neq_s,
02404 dest, src1, src2, mtype, ops);
02405 }
02406
02407 void
02408 Expand_Recip_Sqrt (TN *result, TN *src, TYPE_ID mtype, OPS *ops)
02409 {
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427 }
02428
02429 void
02430 Expand_Flop (OPCODE opcode, TN *result, TN *src1, TN *src2, TN *src3, OPS *ops)
02431 {
02432 TOP opc;
02433
02434 switch (opcode) {
02435 case OPC_F4ADD:
02436 opc = TOP_add_s;
02437 break;
02438 case OPC_F8ADD:
02439 opc = TOP_add_d;
02440 break;
02441 case OPC_F4SUB:
02442 opc = TOP_sub_s;
02443 break;
02444 case OPC_F8SUB:
02445 opc = TOP_sub_d;
02446 break;
02447 case OPC_F4MPY:
02448 opc = TOP_mul_s;
02449 break;
02450 case OPC_F8MPY:
02451 opc = TOP_mul_d;
02452 break;
02453 case OPC_F4MADD:
02454 opc = TOP_madd_s;
02455 break;
02456 case OPC_F4NMADD:
02457 opc = TOP_nmadd_s;
02458 break;
02459 case OPC_F4MSUB:
02460 opc = TOP_msub_s;
02461 break;
02462 case OPC_F4NMSUB:
02463 opc = TOP_nmsub_s;
02464 break;
02465 case OPC_F8MADD:
02466 opc = TOP_madd_d;
02467 break;
02468 case OPC_F8NMADD:
02469 opc = TOP_nmadd_d;
02470 break;
02471 case OPC_F8MSUB:
02472 opc = TOP_msub_d;
02473 break;
02474 case OPC_F8NMSUB:
02475 opc = TOP_nmsub_d;
02476 break;
02477 case OPC_F4DIV:
02478 opc = TOP_div_s;
02479 break;
02480 case OPC_F8DIV:
02481 opc = TOP_div_d;
02482 break;
02483 case OPC_F4RECIP:
02484 opc = TOP_recip_s;
02485 break;
02486 case OPC_F8RECIP:
02487 opc = TOP_recip_d;
02488 break;
02489 case OPC_F4RSQRT:
02490 opc = TOP_rsqrt_s;
02491 break;
02492 case OPC_F8RSQRT:
02493 opc = TOP_rsqrt_d;
02494 break;
02495 default:
02496 #pragma mips_frequency_hint NEVER
02497 FmtAssert(FALSE, ("unexpected opcode %s", OPCODE_name(opcode)));
02498
02499 }
02500 if (TOP_is_madd(opc)) {
02501 Build_OP(opc, result, src1, src2, src3, ops);
02502 } else {
02503 Build_OP(opc, result, src1, src2, ops);
02504 }
02505 }
02506
02507 extern void
02508 Init_CG_Expand (void)
02509 {
02510 static BOOL Initialized = FALSE;
02511
02512
02513 Trace_Exp = Get_Trace (TP_CGEXP, 1);
02514
02515 Trace_Exp2 = Get_Trace (TP_CGEXP, 4);
02516 Disable_Const_Mult_Opt = Get_Trace (TP_CGEXP, 32);
02517
02518 if (Initialized) return;
02519 Initialized = TRUE;
02520
02521 Initialize_Branch_Variants();
02522 }
02523
02524
02525
02526
02527
02528
02529
02530 void
02531 Exp_COPY (TN *tgt_tn, TN *src_tn, OPS *ops)
02532 {
02533 if( TN_is_constant(src_tn) )
02534 {
02535 FmtAssert (TN_has_value(src_tn), ("Exp_COPY: illegal source tn"));
02536
02537 Exp_OP1 (OPC_I4INTCONST, tgt_tn, src_tn, ops);
02538 }
02539 else
02540 {
02541 #if defined(TARG_SL)
02542
02543 Copy_Tn_MapInfo(src_tn, tgt_tn);
02544 #endif
02545
02546 ISA_REGISTER_CLASS tgt_rc = TN_register_class(tgt_tn);
02547 ISA_REGISTER_CLASS src_rc = TN_register_class(src_tn);
02548
02549 if (tgt_rc == src_rc && tgt_rc == ISA_REGISTER_CLASS_integer) {
02550 Build_OP( TOP_or, tgt_tn, src_tn, Zero_TN, ops );
02551 Set_OP_copy (OPS_last(ops));
02552 }
02553 else if (src_tn == tgt_tn)
02554 {
02555
02556
02557
02558 Build_OP(TOP_noop, ops);
02559 }
02560 else if (tgt_rc == src_rc && tgt_rc == ISA_REGISTER_CLASS_float) {
02561
02562 BOOL is_double = (TN_size(tgt_tn) == 8 && TN_size(src_tn) == 8);
02563 Build_OP(is_double ? TOP_mov_d : TOP_mov_s, tgt_tn, src_tn, ops);
02564 Set_OP_copy (OPS_last(ops));
02565 }
02566 #if defined(TARG_SL)
02567 else if (src_rc == ISA_REGISTER_CLASS_control) {
02568 if (src_rc == tgt_rc) {
02569 TN *tmp_tn = Gen_Register_TN (ISA_REGISTER_CLASS_integer, 4);
02570 Build_OP(TOP_mvfc, tmp_tn, src_tn, ops);
02571 Build_OP(TOP_mvtc, tgt_tn, tmp_tn, ops);
02572 } else if (tgt_rc == ISA_REGISTER_CLASS_integer) {
02573 Build_OP(TOP_mvfc, tgt_tn, src_tn, ops);
02574 }
02575 }
02576 else if (tgt_rc == ISA_REGISTER_CLASS_control) {
02577 Is_True(src_rc == ISA_REGISTER_CLASS_integer, ("not supported reg class save"));
02578 Build_OP(TOP_mvtc, tgt_tn, src_tn, ops);
02579 }
02580 else if (src_rc == ISA_REGISTER_CLASS_accum) {
02581 if (src_rc == tgt_rc) {
02582 TN *tmp_tn = Gen_Register_TN (ISA_REGISTER_CLASS_integer, 4);
02583 Build_OP(TOP_c3_mvfacc, tmp_tn, src_tn, ops);
02584 Build_OP(TOP_c3_mvtacc, tgt_tn, tmp_tn, ops);
02585 } else if (tgt_rc == ISA_REGISTER_CLASS_integer) {
02586 Build_OP(TOP_c3_mvfacc, tgt_tn, src_tn, ops);
02587 }
02588 } else if (tgt_rc == ISA_REGISTER_CLASS_accum) {
02589 Is_True(src_rc == ISA_REGISTER_CLASS_integer, ("not supported reg class save"));
02590 Build_OP(TOP_c3_mvtacc, tgt_tn, src_tn, ops);
02591 }
02592 else if (src_rc == ISA_REGISTER_CLASS_addr) {
02593 if (src_rc == tgt_rc) {
02594 TN *tmp_tn = Gen_Register_TN (ISA_REGISTER_CLASS_integer, 4);
02595 Build_OP(TOP_c3_mvfadd, tmp_tn, src_tn, ops);
02596 Build_OP(TOP_c3_mvtadd, tgt_tn, tmp_tn, ops);
02597 } else if (tgt_rc == ISA_REGISTER_CLASS_integer) {
02598 Build_OP(TOP_c3_mvfadd, tgt_tn, src_tn, ops);
02599 }
02600 } else if (tgt_rc == ISA_REGISTER_CLASS_addr) {
02601 Is_True(src_rc == ISA_REGISTER_CLASS_integer, ("not supported reg class save"));
02602 Build_OP(TOP_c3_mvtadd, tgt_tn, src_tn, ops);
02603 }
02604 #endif
02605
02606 else
02607 {
02608
02609 BOOL is_double = (TN_size(tgt_tn) == 8 && TN_size(src_tn) == 8);
02610 if (src_rc == ISA_REGISTER_CLASS_integer) {
02611 Build_OP(is_double ? TOP_dmtc1 : TOP_mtc1, tgt_tn, src_tn, ops);
02612 } else if (src_rc == ISA_REGISTER_CLASS_float) {
02613 Build_OP(is_double ? TOP_dmfc1 : TOP_mfc1, tgt_tn, src_tn, ops);
02614 } else {
02615 FmtAssert(FALSE, ("Unimplemented Copy.\n"));
02616 }
02617 }
02618 }
02619 }
02620
02621 static ST *tmp_apply_arg = NULL;
02622 void
02623 Generate_Temp_Apply_Arg ( )
02624 {
02625 TY_IDX tyi;
02626 TY& ty = New_TY(tyi);
02627 TY_Init(ty, 144, KIND_STRUCT, MTYPE_M,
02628 Save_Str("__apply_arg"));
02629 Set_TY_align(tyi, 8);
02630 tmp_apply_arg = New_ST(CURRENT_SYMTAB);
02631 ST_Init(tmp_apply_arg, TY_name_idx(ty),
02632 CLASS_VAR, SCLASS_AUTO, EXPORT_LOCAL, tyi);
02633 Set_ST_is_temp_var(tmp_apply_arg);
02634 Allocate_Object(tmp_apply_arg);
02635 }
02636
02637 void
02638 Exp_Intrinsic_Op (INTRINSIC id, TN *result, TN *op0, TN *op1, TYPE_ID mtype, OPS *ops)
02639 {
02640 FmtAssert(FALSE, ("Exp_Intrinsic_Op NYI"));
02641 return;
02642 }
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652 static INT
02653 Expand_TOP_intrncall (
02654 const OP *op,
02655 OPS *ops,
02656 BOOL get_sequence_length,
02657 INT pc_value)
02658 {
02659 FmtAssert(FALSE, ("Expand_TOP_intrncall NYI"));
02660 return 0;
02661 }
02662
02663 static TYPE_ID
02664 Get_Intrinsic_Size_Mtype (INTRINSIC id)
02665 {
02666 switch (id) {
02667 case INTRN_COMPARE_AND_SWAP_I4:
02668 case INTRN_LOCK_TEST_AND_SET_I4:
02669 case INTRN_LOCK_RELEASE_I4:
02670 case INTRN_FETCH_AND_ADD_I4:
02671 case INTRN_ADD_AND_FETCH_I4:
02672 case INTRN_SUB_AND_FETCH_I4:
02673 case INTRN_OR_AND_FETCH_I4:
02674 case INTRN_XOR_AND_FETCH_I4:
02675 case INTRN_AND_AND_FETCH_I4:
02676 case INTRN_NAND_AND_FETCH_I4:
02677 case INTRN_FETCH_AND_SUB_I4:
02678 case INTRN_FETCH_AND_OR_I4:
02679 case INTRN_FETCH_AND_XOR_I4:
02680 case INTRN_FETCH_AND_AND_I4:
02681 case INTRN_FETCH_AND_NAND_I4:
02682 return MTYPE_I4;
02683 case INTRN_COMPARE_AND_SWAP_I8:
02684 case INTRN_LOCK_TEST_AND_SET_I8:
02685 case INTRN_LOCK_RELEASE_I8:
02686 case INTRN_FETCH_AND_ADD_I8:
02687 case INTRN_ADD_AND_FETCH_I8:
02688 case INTRN_SUB_AND_FETCH_I8:
02689 case INTRN_OR_AND_FETCH_I8:
02690 case INTRN_XOR_AND_FETCH_I8:
02691 case INTRN_AND_AND_FETCH_I8:
02692 case INTRN_NAND_AND_FETCH_I8:
02693 case INTRN_FETCH_AND_SUB_I8:
02694 case INTRN_FETCH_AND_OR_I8:
02695 case INTRN_FETCH_AND_XOR_I8:
02696 case INTRN_FETCH_AND_AND_I8:
02697 case INTRN_FETCH_AND_NAND_I8:
02698 case INTRN_SYNCHRONIZE:
02699 return MTYPE_I8;
02700 default:
02701 FmtAssert(FALSE, ("Unexpected intrinsic %d", id));
02702 return MTYPE_UNKNOWN;
02703 }
02704 }
02705
02706 static BOOL
02707 Intrinsic_Returns_New_Value (INTRINSIC id)
02708 {
02709 switch (id) {
02710 case INTRN_ADD_AND_FETCH_I4:
02711 case INTRN_SUB_AND_FETCH_I4:
02712 case INTRN_OR_AND_FETCH_I4:
02713 case INTRN_XOR_AND_FETCH_I4:
02714 case INTRN_AND_AND_FETCH_I4:
02715 case INTRN_NAND_AND_FETCH_I4:
02716 case INTRN_ADD_AND_FETCH_I8:
02717 case INTRN_SUB_AND_FETCH_I8:
02718 case INTRN_OR_AND_FETCH_I8:
02719 case INTRN_XOR_AND_FETCH_I8:
02720 case INTRN_AND_AND_FETCH_I8:
02721 case INTRN_NAND_AND_FETCH_I8:
02722 return TRUE;
02723 default:
02724 return FALSE;
02725 }
02726 }
02727
02728
02729
02730
02731
02732
02733
02734 TN *
02735 Exp_Intrinsic_Call (INTRINSIC id, TN *op0, TN *op1, TN *op2, OPS *ops,
02736 LABEL_IDX *label, OPS *loop_ops)
02737 {
02738 switch (id) {
02739 case INTRN_APPLY_ARGS:
02740 {
02741 static ST *last_PU = NULL;
02742 static TN *return_tn;
02743 ST *current_pu_st = Get_Current_PU_ST();
02744 if (last_PU == current_pu_st)
02745 return return_tn;
02746 else {
02747 Generate_Temp_Apply_Arg();
02748 last_PU = current_pu_st;
02749 INT par;
02750 INT ofst = 16;
02751 TN *ded_tn;
02752
02753
02754
02755 TN *vararg_ptr_tn = Build_TN_Of_Mtype(MTYPE_I8);
02756 Build_OP(TOP_addiu, vararg_ptr_tn, FP_TN, Gen_Literal_TN(-56, 4), ops);
02757 Exp_Store (MTYPE_I4, vararg_ptr_tn, tmp_apply_arg, 8, ops, 0);
02758
02759
02760 for (par = 0; par < MAX_NUMBER_OF_REGISTER_PARAMETERS; par ++) {
02761 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_integer,
02762 par+5,
02763 8 );
02764 Exp_Store (MTYPE_I8, ded_tn, tmp_apply_arg, ofst, ops, 0);
02765 ofst+= 8;
02766 }
02767 for (par = 0; par < MAX_NUMBER_OF_REGISTER_PARAMETERS; par ++) {
02768 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_float,
02769 par+13,
02770 8 );
02771 Exp_Store (MTYPE_F8, ded_tn, tmp_apply_arg, ofst, ops, 0);
02772 ofst+= 8;
02773 }
02774
02775
02776 return_tn = Build_TN_Of_Mtype(MTYPE_I8);
02777 TN *base_tn, *ofst_tn;
02778 base_tn = FP_TN;
02779 ofst_tn = Gen_Symbol_TN (tmp_apply_arg, 8, 0);
02780 Exp_OP2( Pointer_Size == 4 ? OPC_I4ADD : OPC_I8ADD,
02781 return_tn, base_tn, ofst_tn, ops );
02782
02783
02784
02785
02786 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_integer, 5,
02787 8 );
02788 Exp_Store (MTYPE_I4, ded_tn, tmp_apply_arg, 0, ops, 0);
02789 return return_tn;
02790 }
02791 }
02792 case INTRN_APPLY:
02793 {
02794 if (CG_opt_level > 0) {
02795 char asm_string[256];
02796 sprintf(asm_string, "__asm_builtin_apply_load");
02797 TN *opnd[1];
02798 opnd[0] = op1;
02799 OP *asm_op = Mk_VarOP(TOP_asm, 0, 1, NULL, opnd);
02800 Set_OP_volatile(asm_op);
02801 ASM_OP_ANNOT* asm_info = TYPE_PU_ALLOC(ASM_OP_ANNOT);
02802 bzero(asm_info, sizeof(ASM_OP_ANNOT));
02803 WN *asm_wn = WN_CreateAsm_Stmt (0, asm_string);
02804 ASM_OP_wn(asm_info) = asm_wn;
02805 OP_MAP_Set(OP_Asm_Map, asm_op, asm_info);
02806 OPS_Append_Op(ops, asm_op);
02807 } else {
02808 INT par;
02809 INT ofst = 8;
02810 TN *ded_tn;
02811 for (par = 0; par < MAX_NUMBER_OF_REGISTER_PARAMETERS; par ++) {
02812 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_integer,
02813 par+5,
02814 8 );
02815 Build_OP(TOP_ld, ded_tn, op1, Gen_Literal_TN(ofst, 4), ops);
02816 ofst+= 8;
02817 }
02818 for (par = 0; par < MAX_NUMBER_OF_REGISTER_PARAMETERS; par ++) {
02819 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_float,
02820 par+13,
02821 8 );
02822 Build_OP(TOP_ldc1, ded_tn, op1, Gen_Literal_TN(ofst, 4), ops);
02823 ofst+= 8;
02824 }
02825 }
02826 return NULL;
02827 }
02828 case INTRN_RETURN:
02829 {
02830 TN *ded_tn;
02831 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_integer,
02832 3, 8);
02833 Build_OP(TOP_ld, ded_tn, op0, Gen_Literal_TN(0, 4), ops);
02834 ded_tn = Build_Dedicated_TN(ISA_REGISTER_CLASS_float,
02835 1, 8);
02836 Build_OP(TOP_ldc1, ded_tn, op0, Gen_Literal_TN(8, 4), ops);
02837 return NULL;
02838 }
02839 return NULL;
02840 default:
02841 FmtAssert(FALSE, ("Exp_Intrinsic_Call NYI"));
02842 return NULL;
02843 }
02844 }
02845
02846
02847
02848
02849
02850
02851
02852
02853 void Exp_Simulated_Op(const OP *op, OPS *ops, INT pc_value)
02854 {
02855 TOP top = OP_code(op);
02856
02857 switch (top)
02858 {
02859 default:
02860 FmtAssert(FALSE, ("simulated OP %s not handled", TOP_Name(top)));
02861 }
02862 }
02863
02864
02865
02866
02867
02868
02869
02870 INT
02871 Simulated_Op_Real_Ops(const OP *op)
02872 {
02873 switch (OP_code(op)) {
02874 case TOP_intrncall:
02875 return Expand_TOP_intrncall (op, NULL, TRUE, 0);
02876 case TOP_spadjust:
02877 return 1;
02878 default:
02879
02880
02881
02882
02883
02884 return 0;
02885 }
02886 }
02887
02888
02889
02890
02891
02892
02893
02894
02895 INT
02896 Simulated_Op_Real_Inst_Words(const OP *op)
02897 {
02898 INT num_bytes = 0;
02899 TOP top = OP_code(op);
02900
02901 switch (top)
02902 {
02903 case TOP_spadjust:
02904 return 1;
02905 case TOP_asm:
02906 #ifdef TARG_SL
02907
02908 if (CG_check_quadword) {
02909 extern int Compute_Asm_Num (const char *asm_string, BOOL emit_phase) ;
02910 extern char* Generate_Asm_String(OP* asm_op, BB *bb);
02911 Is_True(((OP *)op)->bb, ("Simulated_Op_Real_Inst_Words:: bb is null"));
02912 char *asm_string = Generate_Asm_String((OP *)op, op->bb);
02913 num_bytes = Compute_Asm_Num((const char *)asm_string, FALSE);
02914 if (0) {
02915 fprintf(stdout, "%s --%d\n", asm_string, num_bytes);
02916 }
02917 } else {
02918 num_bytes = 3;
02919 }
02920
02921 #else
02922
02923
02924 num_bytes = 3;
02925 #endif
02926 break;
02927
02928 default:
02929 FmtAssert(FALSE, ("simulated OP %s not handled", TOP_Name(OP_code(op))));
02930 }
02931
02932 return num_bytes;
02933 }
02934
02935
02936
02937
02938
02939
02940
02941
02942 BOOL
02943 Exp_Is_Large_Stack_Sym(ST* sym, INT64 ofst)
02944 {
02945 ST *base_sym;
02946 INT64 base_ofst;
02947
02948 if (sym == NULL)
02949 return FALSE;
02950
02951 Allocate_Object(sym);
02952 Base_Symbol_And_Offset_For_Addressing (sym, ofst, &base_sym, &base_ofst);
02953
02954
02955
02956
02957 if ((base_sym == SP_Sym || base_sym == FP_Sym) &&
02958 !ISA_LC_Value_In_Class(base_ofst, LC_simm16)) {
02959 return TRUE;
02960 }
02961
02962 return FALSE;
02963 }
02964
02965 void
02966 Exp_Noop (OPS *ops)
02967 {
02968 Build_OP (CGTARG_Noop_Top(), ops);
02969 }
02970
02971 void Expand_Const (TN *dest, TN *src, TYPE_ID mtype, OPS *ops)
02972 {
02973 FmtAssert( TN_is_symbol(src), ("Expand_Const: src not a symbol TN"));
02974
02975 TCON tcon = STC_val(TN_var(src));
02976 if (TCON_ty(tcon) == MTYPE_F4 && TCON_fval(tcon) == 0.0) {
02977 FmtAssert(TCON_ty(tcon) == mtype, ("Expand_Const: inconsistent mtypes"));
02978 Build_OP(TOP_mtc1, dest, Zero_TN, ops);
02979 return;
02980 }
02981 if (TCON_ty(tcon) == MTYPE_F8 && TCON_dval(tcon) == 0.0) {
02982 FmtAssert(TCON_ty(tcon) == mtype, ("Expand_Const: inconsistent mtypes"));
02983 Build_OP(TOP_dmtc1, dest, Zero_TN, ops);
02984 return;
02985 }
02986 Exp_Load(mtype, mtype, dest, TN_var(src), 0, ops, 0);
02987 }
02988
02989 static BB* last_bb = NULL;
02990 static TN *last_true_tn = NULL, *last_false_tn = NULL;
02991 void
02992 HB_Reinit_Pred ()
02993 {
02994 last_true_tn = NULL;
02995 last_false_tn = NULL;
02996 last_bb = NULL;
02997 }
02998
02999 void
03000 Exp_True_False_Preds_For_Block(BB *bb, TN* &true_tn, TN * &false_tn)
03001 {
03002 if (last_bb != bb)
03003 last_bb = bb;
03004 else {
03005 true_tn = last_true_tn;
03006 false_tn = last_false_tn;
03007 return;
03008 }
03009 OP* br_op = BB_branch_op(bb);
03010 if (!br_op)
03011 return;
03012 if (OP_code(br_op) == TOP_beq || OP_code(br_op) == TOP_bne) {
03013 OPS new_ops;
03014 OPS_Init(&new_ops);
03015 true_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03016 false_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03017 TN *tmp_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03018 TN *tmp1_tn;
03019 Build_OP(TOP_xor, tmp_tn, OP_opnd(br_op, 0), OP_opnd(br_op, 1),
03020 &new_ops);
03021 Build_OP(TOP_sltiu, false_tn, tmp_tn, Gen_Literal_TN(1, 4), &new_ops);
03022 Build_OP(TOP_sltu, true_tn, Zero_TN, tmp_tn, &new_ops);
03023 if (OP_code(br_op) == TOP_bne) {
03024 tmp1_tn = true_tn;
03025 true_tn = false_tn;
03026 false_tn = tmp1_tn;
03027 }
03028 BB_Insert_Ops_Before(bb, br_op, &new_ops);
03029 last_true_tn = true_tn;
03030 last_false_tn = false_tn;
03031 return;
03032 } else if (OP_code(br_op) == TOP_bc1f || OP_code(br_op) == TOP_bc1t) {
03033 OPS new_ops;
03034 OPS_Init(&new_ops);
03035 true_tn = OP_opnd(br_op, 0);
03036 false_tn = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 4);
03037
03038
03039 OP *op;
03040 BOOL found_cond_set = FALSE;
03041 FOR_ALL_BB_OPs_REV(bb,op) {
03042 if (OP_results(op) &&
03043 (OP_result(op, 0) == OP_opnd(br_op, 0))) {
03044 found_cond_set = TRUE;
03045 break;
03046 }
03047 }
03048 FmtAssert((found_cond_set==TRUE),
03049 ("Did not find instruction setting condition bit in BB"));
03050 switch (OP_code(op)) {
03051 case TOP_c_le_d:
03052 Build_OP(TOP_c_lt_d, false_tn, OP_opnd(op, 1), OP_opnd(op, 0), &new_ops);
03053 break;
03054 case TOP_c_le_s:
03055 Build_OP(TOP_c_lt_s, false_tn, OP_opnd(op, 1), OP_opnd(op, 0), &new_ops);
03056 break;
03057 case TOP_c_lt_d:
03058 Build_OP(TOP_c_le_d, false_tn, OP_opnd(op, 1), OP_opnd(op, 0), &new_ops);
03059 break;
03060 case TOP_c_lt_s:
03061 Build_OP(TOP_c_le_s, false_tn, OP_opnd(op, 1), OP_opnd(op, 0), &new_ops);
03062 break;
03063 case TOP_c_eq_d:
03064 Build_OP(TOP_c_neq_d, false_tn, OP_opnd(op, 1), OP_opnd(op, 0),
03065 &new_ops);
03066 break;
03067 case TOP_c_eq_s:
03068 Build_OP(TOP_c_neq_s, false_tn, OP_opnd(op, 1), OP_opnd(op, 0),
03069 &new_ops);
03070 break;
03071 default:
03072 FmtAssert(FALSE, ("Handle this case"));
03073 break;
03074 }
03075 TN *tmp_tn = Gen_Register_TN(ISA_REGISTER_CLASS_fcc, 4);
03076 if (OP_code(br_op) == TOP_bc1t) {
03077 tmp_tn = true_tn;
03078 true_tn = false_tn;
03079 false_tn = tmp_tn;
03080 }
03081 BB_Insert_Ops_Before(bb, br_op, &new_ops);
03082 last_true_tn = true_tn;
03083 last_false_tn = false_tn;
03084 return;
03085 } else if (OP_code(br_op) == TOP_bgez || OP_code(br_op) == TOP_bltz) {
03086 OPS new_ops;
03087 OPS_Init(&new_ops);
03088 true_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03089 false_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03090 TN *tmp_tn = Gen_Register_TN(ISA_REGISTER_CLASS_integer, 4);
03091 TN *tmp1_tn;
03092 Build_OP(TOP_slt, tmp_tn, OP_opnd(br_op, 0), Zero_TN,
03093 &new_ops);
03094 Build_OP(TOP_xori, true_tn, tmp_tn, Gen_Literal_TN(1, 4), &new_ops);
03095 Build_OP(TOP_slti, false_tn, OP_opnd(br_op, 0), Gen_Literal_TN(0, 4),
03096 &new_ops);
03097 if (OP_code(br_op) == TOP_bgez) {
03098 tmp1_tn = true_tn;
03099 true_tn = false_tn;
03100 false_tn = tmp1_tn;
03101 }
03102 BB_Insert_Ops_Before(bb, br_op, &new_ops);
03103 last_true_tn = true_tn;
03104 last_false_tn = false_tn;
03105 return;
03106 }
03107 FmtAssert(FALSE, ("HANDLE THIS CASE"));
03108 true_tn = false_tn = Zero_TN;
03109 }
03110
03111 BOOL
03112 Target_Has_Immediate_Operand (WN *parent, WN *expr)
03113 {
03114 OPERATOR opr = WN_operator(parent);
03115 return opr == OPR_ADD || opr == OPR_SUB ||
03116 opr == OPR_BAND || opr == OPR_BIOR || opr == OPR_BXOR ||
03117 opr == OPR_LT || opr == OPR_LE || opr == OPR_GT || opr == OPR_GE ||
03118 opr == OPR_LSHR || opr == OPR_ASHR || opr == OPR_SHL;
03119 }
03120
03121 void
03122 Exp_Spadjust (TN *dest, TN *size, VARIANT variant, OPS *ops)
03123 {
03124 Build_OP (TOP_spadjust, dest, SP_TN, size, ops);
03125 OP_variant(OPS_last(ops)) = variant;
03126 }
03127
03128
03129 char *
03130 Exp_Unique_Literal_Name (void)
03131 {
03132 static int unique;
03133 static char name[32];
03134
03135 sprintf(name, ".LC%d", unique);
03136 unique++;
03137 return name;
03138 }
03139
03140 void
03141 Exp_Generic_Pred_Calc(TN* result1, TN *result2, COMPARE_TYPE ctype,
03142 TN *qual_pred, OPS* ops)
03143 { FmtAssert(FALSE,("Unimplemented")); }
03144
03145
03146 void
03147 Exp_Pred_Calc(TN* result, OP* cmp_op, COMPARE_TYPE ctype, BOOL false_result,
03148 OPS* ops)
03149 { FmtAssert(FALSE,("Unimplemented")); }
03150
03151 void Expand_Float_To_Float_Floor( TN* dest, TN* src,
03152 TYPE_ID rtype, TYPE_ID desc, OPS* ops )
03153 {
03154 }