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 #include <stdint.h>
00039
00040 #include <signal.h>
00041 #include "defs.h"
00042 #include "errors.h"
00043 #include "erglob.h"
00044 #include "ercg.h"
00045 #include "tracing.h"
00046 #include "config.h"
00047 #include "config_targ_opt.h"
00048 #include "config_debug.h"
00049 #include "mtypes.h"
00050 #include "topcode.h"
00051 #include "float_rf.h"
00052 #include "tn.h"
00053 #include "cg_flags.h"
00054 #include "targ_isa_lits.h"
00055 #include "op.h"
00056 #include "cg_spill.h"
00057 #include "cgexp.h"
00058 #include "cgexp_internals.h"
00059
00060
00061 static const float_rf One_rf = { 0, 0, 0x0ffff, 0x8000000000000000ll };
00062
00063 #define RESET_COND_DEF_LAST(ops) Set_OP_cond_def_kind(OPS_last(ops),OP_ALWAYS_UNC_DEF)
00064
00065
00066
00067
00068
00069
00070 static void
00071 Expand_SGI_F10_Divide(TN *result, TN *src1, TN *src2, OPS *ops)
00072 {
00073
00074
00075 TN *qpred;
00076 TN *fr, *f9, *f9a, *f9b, *f9c, *f10, *f10a, *f10b, *f10c, *f8b, *f8c, *f6a, *f7a;
00077
00078
00079 qpred = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
00080 fr = Build_TN_Of_Mtype (MTYPE_F10);
00081 f9 = Build_TN_Of_Mtype (MTYPE_F10);
00082 f9a = Build_TN_Of_Mtype (MTYPE_F10);
00083 f9b = Build_TN_Of_Mtype (MTYPE_F10);
00084 f9c = Build_TN_Of_Mtype (MTYPE_F10);
00085 f10 = Build_TN_Of_Mtype (MTYPE_F10);
00086 f10a = Build_TN_Of_Mtype (MTYPE_F10);
00087 f10b = Build_TN_Of_Mtype (MTYPE_F10);
00088 f10c = Build_TN_Of_Mtype (MTYPE_F10);
00089 f8b = Build_TN_Of_Mtype (MTYPE_F10);
00090 f8c = Build_TN_Of_Mtype (MTYPE_F10);
00091 f6a = Build_TN_Of_Mtype (MTYPE_F10);
00092 f7a = Build_TN_Of_Mtype (MTYPE_F10);
00093
00094
00095
00096
00097
00098 Build_OP(TOP_frcpa, fr, qpred, True_TN, Gen_Enum_TN(ECV_sf_s0), src1, src2, ops);
00099 Build_OP(TOP_fnma, f9, qpred, Gen_Enum_TN(ECV_sf_s1), fr, src2, FOne_TN , ops);
00100 RESET_COND_DEF_LAST(ops);
00101 Build_OP(TOP_fma, f10, qpred, Gen_Enum_TN(ECV_sf_s1), f9, fr , fr , ops);
00102 RESET_COND_DEF_LAST(ops);
00103 Build_OP(TOP_fmpy, f9a, qpred, Gen_Enum_TN(ECV_sf_s1), f9, f9 , ops);
00104 RESET_COND_DEF_LAST(ops);
00105 Build_OP(TOP_fma, f9b, qpred, Gen_Enum_TN(ECV_sf_s1), f9a, f10, f10 , ops);
00106 RESET_COND_DEF_LAST(ops);
00107 Build_OP(TOP_fnma, f10a, qpred, Gen_Enum_TN(ECV_sf_s1), f9b, src2, FOne_TN , ops);
00108 RESET_COND_DEF_LAST(ops);
00109 Build_OP(TOP_fmpy, f8b, qpred, Gen_Enum_TN(ECV_sf_s1), fr, src1 , ops);
00110 RESET_COND_DEF_LAST(ops);
00111 Build_OP(TOP_fma, f9c, qpred, Gen_Enum_TN(ECV_sf_s1), f10a, f9b, f9b, ops);
00112 RESET_COND_DEF_LAST(ops);
00113 Build_OP(TOP_fnma, f10b, qpred, Gen_Enum_TN(ECV_sf_s1), f8b, src2, src1 , ops);
00114 RESET_COND_DEF_LAST(ops);
00115 Build_OP(TOP_fma, f8c, qpred, Gen_Enum_TN(ECV_sf_s1), f10b, f9c, f8b , ops);
00116 RESET_COND_DEF_LAST(ops);
00117 Build_OP(TOP_fnma, f10c, qpred, Gen_Enum_TN(ECV_sf_s1), f9c, src2, FOne_TN, ops);
00118 RESET_COND_DEF_LAST(ops);
00119 Build_OP(TOP_fnma, f6a, qpred, Gen_Enum_TN(ECV_sf_s1), f8c, src2, src1 , ops);
00120 RESET_COND_DEF_LAST(ops);
00121 Build_OP(TOP_fma, f7a, qpred, Gen_Enum_TN(ECV_sf_s1), f10c, f9c, f9c , ops);
00122 RESET_COND_DEF_LAST(ops);
00123 Build_OP(TOP_fma, fr, qpred, Gen_Enum_TN(ECV_sf_s0), f6a, f7a, f8c , ops);
00124
00125
00126 Exp_COPY(result, fr, ops);
00127 }
00128
00129
00130 #ifdef OSP_OPT
00131 static void
00132 Expand_I8_I8_Divide(TN *result, TN *src1, TN *src2, OPS *ops)
00133 {
00134
00135 TN *qpred;
00136 TN *f10, *f10a, *f10b, *f10c, *f11, *f11a, *f12, *f12a, *f12b, *f13;
00137
00138
00139 qpred = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
00140 f10 = Build_TN_Of_Mtype (MTYPE_F10);
00141 f10a = Build_TN_Of_Mtype (MTYPE_F10);
00142 f10b = Build_TN_Of_Mtype (MTYPE_F10);
00143 f10c = Build_TN_Of_Mtype (MTYPE_F10);
00144 f11 = Build_TN_Of_Mtype (MTYPE_F10);
00145 f11a = Build_TN_Of_Mtype (MTYPE_F10);
00146 f12 = Build_TN_Of_Mtype (MTYPE_F10);
00147 f12a = Build_TN_Of_Mtype (MTYPE_F10);
00148 f12b = Build_TN_Of_Mtype (MTYPE_F10);
00149 f13 = Build_TN_Of_Mtype (MTYPE_F10);
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 Build_OP(TOP_frcpa, f10, qpred, True_TN, Gen_Enum_TN(ECV_sf_s1), src1, src2, ops);
00167 Build_OP(TOP_fmpy, f12, qpred, Gen_Enum_TN(ECV_sf_s1), src1, f10 , ops);
00168 RESET_COND_DEF_LAST(ops);
00169 Build_OP(TOP_fnma, f11, qpred, Gen_Enum_TN(ECV_sf_s1), src2, f10 , FOne_TN , ops);
00170 RESET_COND_DEF_LAST(ops);
00171 Build_OP(TOP_fma, f12a, qpred, Gen_Enum_TN(ECV_sf_s1), f11, f12 , f12 , ops);
00172 RESET_COND_DEF_LAST(ops);
00173 Build_OP(TOP_fmpy, f13, qpred, Gen_Enum_TN(ECV_sf_s1), f11, f11 , ops);
00174 RESET_COND_DEF_LAST(ops);
00175 Build_OP(TOP_fma, f10a, qpred, Gen_Enum_TN(ECV_sf_s1), f11, f10 , f10 , ops);
00176 RESET_COND_DEF_LAST(ops);
00177 Build_OP(TOP_fma, f11a, qpred, Gen_Enum_TN(ECV_sf_s1), f13, f12a, f12a , ops);
00178 RESET_COND_DEF_LAST(ops);
00179 Build_OP(TOP_fma, f10b, qpred, Gen_Enum_TN(ECV_sf_s1), f13 , f10a, f10a , ops);
00180 RESET_COND_DEF_LAST(ops);
00181 Build_OP(TOP_fnma, f12b, qpred, Gen_Enum_TN(ECV_sf_s1),src2, f11a, src1 , ops);
00182 RESET_COND_DEF_LAST(ops);
00183 Build_OP(TOP_fma, f10, qpred, Gen_Enum_TN(ECV_sf_s1), f12b, f10b, f11a , ops);
00184
00185
00186 Exp_COPY(result, f10, ops);
00187 }
00188 #endif
00189
00190 static void
00191 Expand_SGI_F8_Divide(TN *result, TN *src1, TN *src2, OPS *ops)
00192 {
00193
00194
00195 TN *qpred;
00196 TN *r0,*r2,*r4,*fr,*q0,*q1,*q2,*q,*r;
00197
00198
00199 qpred = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
00200 fr = Build_TN_Of_Mtype (MTYPE_F10);
00201 r0 = Build_TN_Of_Mtype (MTYPE_F10);
00202 r2 = Build_TN_Of_Mtype (MTYPE_F10);
00203 r4 = Build_TN_Of_Mtype (MTYPE_F10);
00204 q0 = Build_TN_Of_Mtype (MTYPE_F10);
00205 q1 = Build_TN_Of_Mtype (MTYPE_F10);
00206 q2 = Build_TN_Of_Mtype (MTYPE_F10);
00207 q = Build_TN_Of_Mtype (MTYPE_F10);
00208 r = Build_TN_Of_Mtype (MTYPE_F10);
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 Build_OP(TOP_frcpa, fr, qpred, True_TN, Gen_Enum_TN(ECV_sf_s0), src1, src2, ops);
00229 Build_OP(TOP_fnma, r0, qpred, Gen_Enum_TN(ECV_sf_s1), fr, src2, FOne_TN , ops);
00230 RESET_COND_DEF_LAST(ops);
00231 Build_OP(TOP_fma, q0, qpred, Gen_Enum_TN(ECV_sf_s1), fr, r0, fr, ops);
00232 RESET_COND_DEF_LAST(ops);
00233 Build_OP(TOP_fmpy, r2, qpred, Gen_Enum_TN(ECV_sf_s1), r0, r0, ops);
00234 RESET_COND_DEF_LAST(ops);
00235 Build_OP(TOP_fma, q1, qpred, Gen_Enum_TN(ECV_sf_s1), q0, r2, q0, ops);
00236 RESET_COND_DEF_LAST(ops);
00237 Build_OP(TOP_fmpy, r4, qpred, Gen_Enum_TN(ECV_sf_s1), r2, r2, ops);
00238 RESET_COND_DEF_LAST(ops);
00239 Build_OP(TOP_fma, q2, qpred, Gen_Enum_TN(ECV_sf_s1), q1, r4, q1, ops);
00240 RESET_COND_DEF_LAST(ops);
00241 Build_OP(TOP_fmpy, q, qpred, Gen_Enum_TN(ECV_sf_s1), src1, q2, ops);
00242 RESET_COND_DEF_LAST(ops);
00243 Build_OP(TOP_fnma, r, qpred, Gen_Enum_TN(ECV_sf_s1), q, src2, src1 , ops);
00244 RESET_COND_DEF_LAST(ops);
00245 Build_OP(TOP_fma_d, fr, qpred, Gen_Enum_TN(ECV_sf_s0), q2, r, q, ops);
00246
00247
00248 Exp_COPY(result, fr, ops);
00249 }
00250
00251 static void
00252 Expand_SGI_F4_Divide(TN *result, TN *src1, TN *src2, OPS *ops)
00253 {
00254
00255
00256 TN *qpred;
00257 TN *r0,*r2,*r4,*fr,*q0,*q1,*q2;
00258
00259
00260 qpred = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
00261 fr = Build_TN_Of_Mtype (MTYPE_F10);
00262 r0 = Build_TN_Of_Mtype (MTYPE_F10);
00263 r2 = Build_TN_Of_Mtype (MTYPE_F10);
00264 r4 = Build_TN_Of_Mtype (MTYPE_F10);
00265 q0 = Build_TN_Of_Mtype (MTYPE_F10);
00266 q1 = Build_TN_Of_Mtype (MTYPE_F10);
00267 q2 = Build_TN_Of_Mtype (MTYPE_F10);
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 Build_OP(TOP_frcpa, fr, qpred, True_TN, Gen_Enum_TN(ECV_sf_s0), src1, src2, ops);
00282 Build_OP(TOP_fnma, r0, qpred, Gen_Enum_TN(ECV_sf_s1), fr, src2, FOne_TN , ops);
00283 RESET_COND_DEF_LAST(ops);
00284 Build_OP(TOP_fmpy, q0, qpred, Gen_Enum_TN(ECV_sf_s1), fr, src1, ops);
00285 RESET_COND_DEF_LAST(ops);
00286 Build_OP(TOP_fma, q1, qpred, Gen_Enum_TN(ECV_sf_s1), q0, r0, q0, ops);
00287 RESET_COND_DEF_LAST(ops);
00288 Build_OP(TOP_fmpy, r2, qpred, Gen_Enum_TN(ECV_sf_s1), r0, r0, ops);
00289 RESET_COND_DEF_LAST(ops);
00290 Build_OP(TOP_fma, q2, qpred, Gen_Enum_TN(ECV_sf_s1), q1, r2, q1, ops);
00291 RESET_COND_DEF_LAST(ops);
00292 Build_OP(TOP_fmpy, r4, qpred, Gen_Enum_TN(ECV_sf_s1), r2, r2, ops);
00293 RESET_COND_DEF_LAST(ops);
00294 Build_OP(TOP_fma_s, fr, qpred, Gen_Enum_TN(ECV_sf_s0), q2, r4, q2, ops);
00295
00296
00297 Exp_COPY(result, fr, ops);
00298 }
00299
00300
00301 static void
00302 Expand_Intel_Max_Thr_F10_Divide(TN *result, TN *src1, TN *src2, OPS *ops)
00303 {
00304 TN * const f0 = FZero_TN;
00305 TN * const f1 = FOne_TN;
00306 TN *f2, *f3, *f4, *f5;
00307 TN *f6 = src1;
00308 TN * const f7 = src2;
00309 TN *f8, *f9, *f10, *fr;
00310 TN * const p0 = True_TN;
00311 TN *p6;
00312 TN *t1;
00313
00314
00315
00316
00317
00318
00319 f8 = Build_TN_Of_Mtype(MTYPE_F10);
00320 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
00321 Build_OP(TOP_frcpa, f8, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, f7, ops);
00322 fr = f8;
00323
00324
00325
00326 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00327 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f8, f1, ops);
00328 RESET_COND_DEF_LAST(ops);
00329 f9 = t1;
00330
00331
00332
00333 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00334 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f8, f8, ops);
00335 RESET_COND_DEF_LAST(ops);
00336 f10 = t1;
00337
00338
00339
00340 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00341 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f9, f0, ops);
00342 RESET_COND_DEF_LAST(ops);
00343 f9 = t1;
00344
00345
00346
00347 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00348 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f10, f10, ops);
00349 RESET_COND_DEF_LAST(ops);
00350 f9 = t1;
00351
00352
00353
00354 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00355 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f8, f0, ops);
00356 RESET_COND_DEF_LAST(ops);
00357 f10 = t1;
00358
00359
00360
00361 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00362 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f1, ops);
00363 RESET_COND_DEF_LAST(ops);
00364 f8 = t1;
00365
00366
00367
00368 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00369 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f8, f9, f9, ops);
00370 RESET_COND_DEF_LAST(ops);
00371 f8 = t1;
00372
00373
00374
00375 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00376 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f10, f6, ops);
00377 RESET_COND_DEF_LAST(ops);
00378 f9 = t1;
00379
00380
00381
00382 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00383 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f8, f10, ops);
00384 RESET_COND_DEF_LAST(ops);
00385 f9 = t1;
00386
00387
00388
00389 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00390 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f8, f1, ops);
00391 RESET_COND_DEF_LAST(ops);
00392 f10 = t1;
00393
00394
00395
00396 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00397 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f8, f8, ops);
00398 RESET_COND_DEF_LAST(ops);
00399 f8 = t1;
00400
00401
00402
00403 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00404 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f6, ops);
00405 RESET_COND_DEF_LAST(ops);
00406 f10 = t1;
00407
00408
00409
00410 Build_OP(TOP_fma, fr, p6, Gen_Enum_TN(ECV_sf_s0), f10, f8, f9, ops);
00411 f8 = fr;
00412
00413
00414
00415 Exp_COPY(result, f8, ops);
00416 }
00417
00418
00419 static void
00420 Expand_Intel_Max_Thr_F8_Divide(TN *result, TN *src1, TN *src2, OPS *ops)
00421 {
00422 TN * const f0 = FZero_TN;
00423 TN * const f1 = FOne_TN;
00424 TN *f2, *f3, *f4, *f5;
00425 TN *f6 = src1;
00426 TN * const f7 = src2;
00427 TN *f8, *f9, *fr;
00428 TN * const p0 = True_TN;
00429 TN *p6;
00430 TN *t1;
00431
00432
00433
00434
00435
00436
00437 f8 = Build_TN_Of_Mtype(MTYPE_F10);
00438 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
00439 Build_OP(TOP_frcpa, f8, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, f7, ops);
00440 fr = f8;
00441
00442
00443
00444 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00445 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f8, f1, ops);
00446 RESET_COND_DEF_LAST(ops);
00447 f9 = t1;
00448
00449
00450
00451 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00452 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f8, f8, ops);
00453 RESET_COND_DEF_LAST(ops);
00454 f8 = t1;
00455
00456
00457
00458 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00459 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f9, f0, ops);
00460 RESET_COND_DEF_LAST(ops);
00461 f9 = t1;
00462
00463
00464
00465 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00466 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f8, f8, ops);
00467 RESET_COND_DEF_LAST(ops);
00468 f8 = t1;
00469
00470
00471
00472 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00473 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f9, f0, ops);
00474 RESET_COND_DEF_LAST(ops);
00475 f9 = t1;
00476
00477
00478
00479 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00480 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f8, f8, ops);
00481 RESET_COND_DEF_LAST(ops);
00482 f8 = t1;
00483
00484
00485
00486 t1 = Build_TN_Of_Mtype(MTYPE_F8);
00487 Build_OP(TOP_fma_d, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f8, f0, ops);
00488 RESET_COND_DEF_LAST(ops);
00489 f9 = t1;
00490
00491
00492
00493 t1 = Build_TN_Of_Mtype(MTYPE_F8);
00494 Build_OP(TOP_fnma_d, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f6, ops);
00495 RESET_COND_DEF_LAST(ops);
00496 f6 = t1;
00497
00498
00499
00500 Build_OP(TOP_fma_d, fr, p6, Gen_Enum_TN(ECV_sf_s0), f6, f8, f9, ops);
00501 f8 = fr;
00502
00503
00504
00505 Exp_COPY(result, f8, ops);
00506 }
00507
00508
00509 static void
00510 Expand_Intel_Max_Thr_F4_Divide(TN *result, TN *src1, TN *src2, OPS *ops)
00511 {
00512 TN * const f0 = FZero_TN;
00513 TN * const f1 = FOne_TN;
00514 TN *f2, *f3, *f4, *f5;
00515 TN *f6 = src1;
00516 TN * const f7 = src2;
00517 TN *f8, *f9, *fr;
00518 TN * const p0 = True_TN;
00519 TN *p6;
00520 TN *t1;
00521
00522
00523
00524
00525
00526
00527 f8 = Build_TN_Of_Mtype(MTYPE_F10);
00528 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
00529 Build_OP(TOP_frcpa, f8, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, f7, ops);
00530 fr = f8;
00531
00532
00533
00534 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00535 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f8, f1, ops);
00536 RESET_COND_DEF_LAST(ops);
00537 f9 = t1;
00538
00539
00540
00541 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00542 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f9, f9, ops);
00543 RESET_COND_DEF_LAST(ops);
00544 f9 = t1;
00545
00546
00547
00548 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00549 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f8, f8, ops);
00550 RESET_COND_DEF_LAST(ops);
00551 f8 = t1;
00552
00553
00554
00555 t1 = Build_TN_Of_Mtype(MTYPE_F4);
00556 Build_OP(TOP_fma_s, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f8, f0, ops);
00557 RESET_COND_DEF_LAST(ops);
00558 f9 = t1;
00559
00560
00561
00562 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00563 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f6, ops);
00564 RESET_COND_DEF_LAST(ops);
00565 f6 = t1;
00566
00567
00568
00569 Build_OP(TOP_fma_s, fr, p6, Gen_Enum_TN(ECV_sf_s0), f6, f8, f9, ops);
00570 f8 = fr;
00571
00572
00573
00574 Exp_COPY(result, f8, ops);
00575 }
00576
00577 static void
00578 Expand_I4_I4_Divide(TN *result, TN *src1, TN *src2, OPS *ops)
00579 {
00580 TN * const f0 = FZero_TN;
00581 TN * const f1 = FOne_TN;
00582 TN *f6, *f7, *f10, *f11, *f8, *f9;
00583 TN *f13 = src1;
00584 TN * const f12 = src2;
00585 TN * const p0 = True_TN;
00586 TN *p6;
00587 TN *t0;
00588
00589 t0 = Build_TN_Of_Mtype(MTYPE_I8);
00590 f6 = Build_TN_Of_Mtype(MTYPE_F10);
00591 Build_OP(TOP_addl,t0,True_TN,Gen_Literal_TN(65501,4),Zero_TN,ops);
00592 Build_OP(TOP_setf_exp, f6, True_TN, t0, ops);
00593
00594
00595 f7 = Build_TN_Of_Mtype(MTYPE_F10);
00596 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
00597 Build_OP(TOP_frcpa, f7, p6, p0, Gen_Enum_TN(ECV_sf_s1), f13, f12, ops);
00598
00599 f10 = Build_TN_Of_Mtype(MTYPE_F10);
00600 Build_OP(TOP_fnma, f10, p6, Gen_Enum_TN(ECV_sf_s1), f12, f7, f1, ops);
00601 RESET_COND_DEF_LAST(ops);
00602
00603 f11 = Build_TN_Of_Mtype(MTYPE_F10);
00604 Build_OP(TOP_fma, f11, p6, Gen_Enum_TN(ECV_sf_s1), f13, f7, f0, ops);
00605 RESET_COND_DEF_LAST(ops);
00606
00607 f8 = Build_TN_Of_Mtype(MTYPE_F10);
00608 Build_OP(TOP_fma, f8, p6, Gen_Enum_TN(ECV_sf_s1), f10, f10, f6, ops);
00609 RESET_COND_DEF_LAST(ops);
00610
00611 f9 = Build_TN_Of_Mtype(MTYPE_F10);
00612 Build_OP(TOP_fma, f9, p6, Gen_Enum_TN(ECV_sf_s1), f10, f11, f11, ops);
00613 RESET_COND_DEF_LAST(ops);
00614
00615 Build_OP(TOP_fma, f7, p6, Gen_Enum_TN(ECV_sf_s1), f8, f9, f9, ops);
00616
00617 Exp_COPY(result, f7, ops);
00618 }
00619
00620
00621 static void
00622 Expand_Intel_Min_Lat_F10_Divide(TN *result, TN *src1, TN *src2, OPS *ops)
00623 {
00624 TN * const f0 = FZero_TN;
00625 TN * const f1 = FOne_TN;
00626 TN *f2, *f3, *f4, *f5;
00627 TN *f6 = src1;
00628 TN * const f7 = src2;
00629 TN *f8, *f9, *f10, *f11, *f12, *fr;
00630 TN * const p0 = True_TN;
00631 TN *p6;
00632 TN *t1;
00633
00634
00635
00636
00637
00638
00639 f8 = Build_TN_Of_Mtype(MTYPE_F10);
00640 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
00641 Build_OP(TOP_frcpa, f8, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, f7, ops);
00642 fr = f8;
00643
00644
00645
00646 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00647 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f8, f1, ops);
00648 RESET_COND_DEF_LAST(ops);
00649 f9 = t1;
00650
00651
00652
00653 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00654 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f8, f0, ops);
00655 RESET_COND_DEF_LAST(ops);
00656 f10 = t1;
00657
00658
00659
00660 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00661 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f9, f0, ops);
00662 RESET_COND_DEF_LAST(ops);
00663 f11 = t1;
00664
00665
00666
00667 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00668 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f9, f9, ops);
00669 RESET_COND_DEF_LAST(ops);
00670 f12 = t1;
00671
00672
00673
00674 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00675 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f11, f11, f9, ops);
00676 RESET_COND_DEF_LAST(ops);
00677 f9 = t1;
00678
00679
00680
00681 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00682 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f12, f8, f8, ops);
00683 RESET_COND_DEF_LAST(ops);
00684 f11 = t1;
00685
00686
00687
00688 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00689 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f11, f9, f8, ops);
00690 RESET_COND_DEF_LAST(ops);
00691 f8 = t1;
00692
00693
00694
00695 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00696 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f10, f6, ops);
00697 RESET_COND_DEF_LAST(ops);
00698 f9 = t1;
00699
00700
00701
00702 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00703 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f8, f10, ops);
00704 RESET_COND_DEF_LAST(ops);
00705 f9 = t1;
00706
00707
00708
00709 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00710 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f8, f1, ops);
00711 RESET_COND_DEF_LAST(ops);
00712 f10 = t1;
00713
00714
00715
00716 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00717 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f8, f8, ops);
00718 RESET_COND_DEF_LAST(ops);
00719 f8 = t1;
00720
00721
00722
00723 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00724 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f6, ops);
00725 RESET_COND_DEF_LAST(ops);
00726 f10 = t1;
00727
00728
00729
00730 Build_OP(TOP_fma, fr, p6, Gen_Enum_TN(ECV_sf_s0), f10, f8, f9, ops);
00731 f8 = fr;
00732
00733
00734
00735 Exp_COPY(result, f8, ops);
00736 }
00737
00738
00739 static void
00740 Expand_Intel_Min_Lat_F8_Divide(TN *result, TN *src1, TN *src2, OPS *ops)
00741 {
00742 TN * const f0 = FZero_TN;
00743 TN * const f1 = FOne_TN;
00744 TN *f2, *f3, *f4, *f5;
00745 TN *f6 = src1;
00746 TN * const f7 = src2;
00747 TN *f8, *f9, *f10, *f11, *fr;
00748 TN * const p0 = True_TN;
00749 TN *p6;
00750 TN *t1;
00751
00752
00753
00754
00755
00756
00757 f8 = Build_TN_Of_Mtype(MTYPE_F10);
00758 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
00759 Build_OP(TOP_frcpa, f8, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, f7, ops);
00760 fr = f8;
00761
00762
00763
00764 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00765 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f8, f0, ops);
00766 RESET_COND_DEF_LAST(ops);
00767 f9 = t1;
00768
00769
00770
00771 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00772 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f8, f1, ops);
00773 RESET_COND_DEF_LAST(ops);
00774 f10 = t1;
00775
00776
00777
00778 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00779 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f9, f9, ops);
00780 RESET_COND_DEF_LAST(ops);
00781 f9 = t1;
00782
00783
00784
00785 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00786 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f10, f0, ops);
00787 RESET_COND_DEF_LAST(ops);
00788 f11 = t1;
00789
00790
00791
00792 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00793 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f8, f8, ops);
00794 RESET_COND_DEF_LAST(ops);
00795 f8 = t1;
00796
00797
00798
00799 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00800 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f11, f9, f9, ops);
00801 RESET_COND_DEF_LAST(ops);
00802 f9 = t1;
00803
00804
00805
00806 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00807 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f11, f11, f0, ops);
00808 RESET_COND_DEF_LAST(ops);
00809 f10 = t1;
00810
00811
00812
00813 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00814 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f11, f8, f8, ops);
00815 RESET_COND_DEF_LAST(ops);
00816 f8 = t1;
00817
00818
00819
00820 t1 = Build_TN_Of_Mtype(MTYPE_F8);
00821 Build_OP(TOP_fma_d, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f9, f9, ops);
00822 RESET_COND_DEF_LAST(ops);
00823 f9 = t1;
00824
00825
00826
00827 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00828 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f10, f8, f8, ops);
00829 RESET_COND_DEF_LAST(ops);
00830 f8 = t1;
00831
00832
00833
00834 t1 = Build_TN_Of_Mtype(MTYPE_F8);
00835 Build_OP(TOP_fnma_d, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f6, ops);
00836 RESET_COND_DEF_LAST(ops);
00837 f6 = t1;
00838
00839
00840
00841 Build_OP(TOP_fma_d, fr, p6, Gen_Enum_TN(ECV_sf_s0), f6, f8, f9, ops);
00842 f8 = fr;
00843
00844
00845
00846 Exp_COPY(result, f8, ops);
00847 }
00848
00849
00850 static void
00851 Expand_Intel_Min_Lat_F4_Divide(TN *result, TN *src1, TN *src2, OPS *ops)
00852 {
00853 TN * const f0 = FZero_TN;
00854 TN * const f1 = FOne_TN;
00855 TN *f2, *f3, *f4, *f5;
00856 TN *f6 = src1;
00857 TN *f7 = src2;
00858 TN *f8, *fr;
00859 TN * const p0 = True_TN;
00860 TN *p6;
00861 TN *t1;
00862
00863
00864
00865
00866
00867
00868 f8 = Build_TN_Of_Mtype(MTYPE_F10);
00869 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
00870 Build_OP(TOP_frcpa, f8, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, f7, ops);
00871 fr = f8;
00872
00873
00874
00875 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00876 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f8, f0, ops);
00877 RESET_COND_DEF_LAST(ops);
00878 f6 = t1;
00879
00880
00881
00882 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00883 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f8, f1, ops);
00884 RESET_COND_DEF_LAST(ops);
00885 f7 = t1;
00886
00887
00888
00889 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00890 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f6, f6, ops);
00891 RESET_COND_DEF_LAST(ops);
00892 f6 = t1;
00893
00894
00895
00896 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00897 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f7, f0, ops);
00898 RESET_COND_DEF_LAST(ops);
00899 f7 = t1;
00900
00901
00902
00903 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00904 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f6, f6, ops);
00905 RESET_COND_DEF_LAST(ops);
00906 f6 = t1;
00907
00908
00909
00910 t1 = Build_TN_Of_Mtype(MTYPE_F10);
00911 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f7, f0, ops);
00912 RESET_COND_DEF_LAST(ops);
00913 f7 = t1;
00914
00915
00916
00917 t1 = Build_TN_Of_Mtype(MTYPE_F8);
00918 Build_OP(TOP_fma_d, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f6, f6, ops);
00919 RESET_COND_DEF_LAST(ops);
00920 f6 = t1;
00921
00922
00923
00924 Build_OP(TOP_fma_s, fr, p6, Gen_Enum_TN(ECV_sf_s0), f6, f1, f0, ops);
00925 f8 = fr;
00926
00927
00928
00929 Exp_COPY(result, f8, ops);
00930 }
00931
00932
00933 static void
00934 Expand_F10_Recip(TN *result, TN *src2, OPS *ops)
00935 {
00936
00937
00938 TN *qpred;
00939 TN *fr, *f9, *f9a, *f9b, *f9c, *f10, *f10a, *f10b, *f10c, *f8c, *f6a, *f7a;
00940
00941
00942 qpred = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
00943 fr = Build_TN_Of_Mtype (MTYPE_F10);
00944 f9 = Build_TN_Of_Mtype (MTYPE_F10);
00945 f9a = Build_TN_Of_Mtype (MTYPE_F10);
00946 f9b = Build_TN_Of_Mtype (MTYPE_F10);
00947 f9c = Build_TN_Of_Mtype (MTYPE_F10);
00948 f10 = Build_TN_Of_Mtype (MTYPE_F10);
00949 f10a = Build_TN_Of_Mtype (MTYPE_F10);
00950 f10b = Build_TN_Of_Mtype (MTYPE_F10);
00951 f10c = Build_TN_Of_Mtype (MTYPE_F10);
00952 f8c = Build_TN_Of_Mtype (MTYPE_F10);
00953 f6a = Build_TN_Of_Mtype (MTYPE_F10);
00954 f7a = Build_TN_Of_Mtype (MTYPE_F10);
00955
00956
00957
00958
00959
00960 Build_OP(TOP_frcpa, fr, qpred, True_TN, Gen_Enum_TN(ECV_sf_s0), FOne_TN, src2, ops);
00961 Build_OP(TOP_fnma, f9, qpred, Gen_Enum_TN(ECV_sf_s1), fr, src2, FOne_TN , ops);
00962 RESET_COND_DEF_LAST(ops);
00963 Build_OP(TOP_fma, f10, qpred, Gen_Enum_TN(ECV_sf_s1), f9, fr , fr , ops);
00964 RESET_COND_DEF_LAST(ops);
00965 Build_OP(TOP_fmpy, f9a, qpred, Gen_Enum_TN(ECV_sf_s1), f9, f9 , ops);
00966 RESET_COND_DEF_LAST(ops);
00967 Build_OP(TOP_fma, f9b, qpred, Gen_Enum_TN(ECV_sf_s1), f9a, f10, f10 , ops);
00968 RESET_COND_DEF_LAST(ops);
00969 Build_OP(TOP_fnma, f10a, qpred, Gen_Enum_TN(ECV_sf_s1), f9b, src2, FOne_TN , ops);
00970 RESET_COND_DEF_LAST(ops);
00971 Build_OP(TOP_fma, f9c, qpred, Gen_Enum_TN(ECV_sf_s1), f10a, f9b, f9b, ops);
00972 RESET_COND_DEF_LAST(ops);
00973 Build_OP(TOP_fnma, f10b, qpred, Gen_Enum_TN(ECV_sf_s1), fr, src2, FOne_TN, ops);
00974 RESET_COND_DEF_LAST(ops);
00975 Build_OP(TOP_fma, f8c, qpred, Gen_Enum_TN(ECV_sf_s1), f10b, f9c, fr , ops);
00976 RESET_COND_DEF_LAST(ops);
00977 Build_OP(TOP_fnma, f10c, qpred, Gen_Enum_TN(ECV_sf_s1), f9c, src2, FOne_TN, ops);
00978 RESET_COND_DEF_LAST(ops);
00979 Build_OP(TOP_fnma, f6a, qpred, Gen_Enum_TN(ECV_sf_s1), f8c, src2, FOne_TN, ops);
00980 RESET_COND_DEF_LAST(ops);
00981 Build_OP(TOP_fma, f7a, qpred, Gen_Enum_TN(ECV_sf_s1), f10c, f9c, f9c , ops);
00982 RESET_COND_DEF_LAST(ops);
00983 Build_OP(TOP_fma, fr, qpred, Gen_Enum_TN(ECV_sf_s0), f6a, f7a, f8c , ops);
00984
00985
00986 Exp_COPY(result, fr, ops);
00987 }
00988
00989 static void
00990 Expand_F8_Recip(TN *result, TN *src2, OPS *ops)
00991 {
00992
00993
00994 TN *qpred;
00995 TN *r0,*r2,*r4,*fr,*q0,*q1,*q2,*q,*r;
00996
00997
00998 qpred = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
00999 fr = Build_TN_Of_Mtype (MTYPE_F10);
01000 r0 = Build_TN_Of_Mtype (MTYPE_F10);
01001 r2 = Build_TN_Of_Mtype (MTYPE_F10);
01002 r4 = Build_TN_Of_Mtype (MTYPE_F10);
01003 q0 = Build_TN_Of_Mtype (MTYPE_F10);
01004 q1 = Build_TN_Of_Mtype (MTYPE_F10);
01005 q2 = Build_TN_Of_Mtype (MTYPE_F10);
01006 q = Build_TN_Of_Mtype (MTYPE_F10);
01007 r = Build_TN_Of_Mtype (MTYPE_F10);
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026 Build_OP(TOP_frcpa, fr, qpred, True_TN, Gen_Enum_TN(ECV_sf_s0), FOne_TN, src2, ops);
01027 Build_OP(TOP_fnma, r0, qpred, Gen_Enum_TN(ECV_sf_s1), fr, src2, FOne_TN , ops);
01028 RESET_COND_DEF_LAST(ops);
01029 Build_OP(TOP_fma, q0, qpred, Gen_Enum_TN(ECV_sf_s1), fr, r0, fr, ops);
01030 RESET_COND_DEF_LAST(ops);
01031 Build_OP(TOP_fmpy, r2, qpred, Gen_Enum_TN(ECV_sf_s1), r0, r0, ops);
01032 RESET_COND_DEF_LAST(ops);
01033 Build_OP(TOP_fma, q1, qpred, Gen_Enum_TN(ECV_sf_s1), q0, r2, q0, ops);
01034 RESET_COND_DEF_LAST(ops);
01035 Build_OP(TOP_fmpy, r4, qpred, Gen_Enum_TN(ECV_sf_s1), r2, r2, ops);
01036 RESET_COND_DEF_LAST(ops);
01037 Build_OP(TOP_fma, q2, qpred, Gen_Enum_TN(ECV_sf_s1), q1, r4, q1, ops);
01038 RESET_COND_DEF_LAST(ops);
01039 Build_OP(TOP_fnma, r, qpred, Gen_Enum_TN(ECV_sf_s1), q2, src2, FOne_TN , ops);
01040 RESET_COND_DEF_LAST(ops);
01041 Build_OP(TOP_fma_d, fr, qpred, Gen_Enum_TN(ECV_sf_s0), q2, r, q2, ops);
01042
01043
01044 Exp_COPY(result, fr, ops);
01045 }
01046
01047 static void
01048 Expand_F4_Recip(TN *result, TN *src2, OPS *ops)
01049 {
01050
01051
01052 TN *qpred;
01053 TN *r0,*r2,*r4,*fr,*q1,*q2;
01054
01055
01056 qpred = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01057 fr = Build_TN_Of_Mtype (MTYPE_F10);
01058 r0 = Build_TN_Of_Mtype (MTYPE_F10);
01059 r2 = Build_TN_Of_Mtype (MTYPE_F10);
01060 r4 = Build_TN_Of_Mtype (MTYPE_F10);
01061 q1 = Build_TN_Of_Mtype (MTYPE_F10);
01062 q2 = Build_TN_Of_Mtype (MTYPE_F10);
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 Build_OP(TOP_frcpa, fr, qpred, True_TN, Gen_Enum_TN(ECV_sf_s0), FOne_TN, src2, ops);
01077 Build_OP(TOP_fnma, r0, qpred, Gen_Enum_TN(ECV_sf_s1), fr, src2, FOne_TN , ops);
01078 RESET_COND_DEF_LAST(ops);
01079 Build_OP(TOP_fma, q1, qpred, Gen_Enum_TN(ECV_sf_s1), fr, r0, fr, ops);
01080 RESET_COND_DEF_LAST(ops);
01081 Build_OP(TOP_fmpy, r2, qpred, Gen_Enum_TN(ECV_sf_s1), r0, r0, ops);
01082 RESET_COND_DEF_LAST(ops);
01083 Build_OP(TOP_fma, q2, qpred, Gen_Enum_TN(ECV_sf_s1), q1, r2, q1, ops);
01084 RESET_COND_DEF_LAST(ops);
01085 Build_OP(TOP_fmpy, r4, qpred, Gen_Enum_TN(ECV_sf_s1), r2, r2, ops);
01086 RESET_COND_DEF_LAST(ops);
01087 Build_OP(TOP_fma_s, fr, qpred, Gen_Enum_TN(ECV_sf_s0), q2, r4, q2, ops);
01088
01089
01090 Exp_COPY(result, fr, ops);
01091 }
01092
01093
01094
01095 enum { E32min = -126, E32max = 127, E32bias = 127 };
01096 enum { E64min = -1022, E64max = 1023, E64bias = 1023 };
01097 enum { E80min = -16382, E80max = 16383, E80bias = 16383 };
01098 enum { E82min = -65534, E82max = 65535, E82bias = 65535 };
01099
01100
01101
01102 static void
01103 Load_82bit_Constant(TN *result, const float_rf *c, OPS *ops)
01104 {
01105 TN * const p0 = True_TN;
01106 TN *r1, *f8, *f9;
01107
01108
01109
01110
01111
01112 if ( c->exp >= (E64min + E82bias)
01113 && c->exp <= (E64max + E82bias)
01114 && (c->frac & 0x7ff) == 0)
01115 {
01116 INT exp = (c->exp - E82bias) + E64bias;
01117 UINT64 dw = ((UINT64)c->sign << 63)
01118 | ((UINT64)exp << 52)
01119 | ((c->frac >> 11) & 0xfffffffffffffULL);
01120 r1 = Build_TN_Of_Mtype(MTYPE_U8);
01121 Build_OP(TOP_movl, r1, p0, Gen_Literal_TN(dw, 8), ops);
01122 CGSPILL_Attach_Intconst_Remat(r1, dw);
01123 Build_OP(TOP_setf_d, result, p0, r1, ops);
01124 CGSPILL_Attach_Floatconst_Remat(result, MTYPE_F8, *(double *)&dw);
01125 } else {
01126 INT32 sign_exp = (c->sign << 17) | c->exp;
01127 r1 = Build_TN_Of_Mtype(MTYPE_U8);
01128 Build_OP(TOP_mov_i, r1, p0, Gen_Literal_TN(sign_exp, 4), ops);
01129 CGSPILL_Attach_Intconst_Remat(r1, sign_exp);
01130 f8 = Build_TN_Of_Mtype(MTYPE_F10);
01131 Build_OP(TOP_setf_exp, f8, p0, r1, ops);
01132 r1 = Build_TN_Of_Mtype(MTYPE_U8);
01133 Build_OP(TOP_movl, r1, p0, Gen_Literal_TN(c->frac, 8), ops);
01134 CGSPILL_Attach_Intconst_Remat(r1, c->frac);
01135 f9 = Build_TN_Of_Mtype(MTYPE_F10);
01136 Build_OP(TOP_setf_sig, f9, p0, r1, ops);
01137 Build_OP(TOP_fmerge_se, result, p0, f8, f9, ops);
01138 }
01139 }
01140
01141
01142
01143
01144 static void
01145 Expand_F4_Div_By_Const(TN *result, TN *src1, TN *src2,
01146 const float_rf *b, OPS *ops)
01147 {
01148 INT pr;
01149 float_rf y0, y1;
01150 float_rf d, e;
01151 TN * const f0 = FZero_TN;
01152 TN *f6 = src1;
01153 TN * const f7 = src2;
01154 TN *f8, *f9, *fr, *fy1;
01155 TN * const p0 = True_TN;
01156 TN *p6;
01157 TN *t1;
01158 status_field sf[2] = {
01159 0x0000000000000300,
01160 0x0000000000001380,
01161 };
01162
01163
01164
01165
01166
01167
01168 y0 = frcpa(&pr, &One_rf, b, &sf[0]);
01169
01170
01171
01172 d = fnma(b, &y0, &One_rf, &sf[1]);
01173
01174
01175
01176 e = fma(&d, &d, &d, &sf[1]);
01177
01178
01179
01180 y1 = fma(&e, &y0, &y0, &sf[1]);
01181
01182
01183
01184 if (pr) {
01185 fy1 = Build_TN_Of_Mtype(MTYPE_F10);
01186 Load_82bit_Constant(fy1, &y1, ops);
01187
01188
01189
01190
01191 f8 = Build_TN_Of_Mtype(MTYPE_F10);
01192 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
01193 Build_OP(TOP_frcpa, f8, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, f7, ops);
01194 fr = f8;
01195
01196 f8 = fy1;
01197
01198
01199
01200 t1 = Build_TN_Of_Mtype(MTYPE_F4);
01201 Build_OP(TOP_fma_s, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f8, f0, ops);
01202 RESET_COND_DEF_LAST(ops);
01203 f9 = t1;
01204
01205
01206
01207 t1 = Build_TN_Of_Mtype(MTYPE_F10);
01208 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f6, ops);
01209 RESET_COND_DEF_LAST(ops);
01210 f6 = t1;
01211
01212
01213
01214 Build_OP(TOP_fma_s, fr, p6, Gen_Enum_TN(ECV_sf_s0), f6, f8, f9, ops);
01215 f8 = fr;
01216
01217 Exp_COPY(result, f8, ops);
01218 } else {
01219
01220
01221
01222
01223 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
01224 Build_OP(TOP_frcpa, result, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, f7, ops);
01225 }
01226 }
01227
01228
01229
01230
01231 static void
01232 Expand_F8_Div_By_Const(TN *result, TN *src1, TN *src2,
01233 const float_rf *b, OPS *ops)
01234 {
01235 INT pr;
01236 float_rf y0, y1, y2, y3;
01237 float_rf e0, e1, e2;
01238 TN * const f0 = FZero_TN;
01239 TN *f6 = src1;
01240 TN * const f7 = src2;
01241 TN *f8, *f9, *fr, *fy3;
01242 TN * const p0 = True_TN;
01243 TN *p6;
01244 TN *t1;
01245 status_field sf[2] = {
01246 0x0000000000000300,
01247 0x0000000000001380,
01248 };
01249
01250
01251
01252
01253
01254
01255 y0 = frcpa(&pr, &One_rf, b, &sf[0]);
01256
01257
01258
01259 e0 = fnma(b, &y0, &One_rf, &sf[1]);
01260
01261
01262
01263 y1 = fma(&e0, &y0, &y0, &sf[1]);
01264
01265
01266
01267 e1 = fma(&e0, &e0, &Zero_rf, &sf[1]);
01268
01269
01270
01271 y2 = fma(&e1, &y1, &y1, &sf[1]);
01272
01273
01274
01275 e2 = fma(&e1, &e1, &Zero_rf, &sf[1]);
01276
01277
01278
01279 y3 = fma(&e2, &y2, &y2, &sf[1]);
01280
01281
01282
01283 if (pr) {
01284 fy3 = Build_TN_Of_Mtype(MTYPE_F10);
01285 Load_82bit_Constant(fy3, &y3, ops);
01286
01287
01288
01289
01290 f8 = Build_TN_Of_Mtype(MTYPE_F10);
01291 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
01292 Build_OP(TOP_frcpa, f8, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, f7, ops);
01293 fr = f8;
01294
01295 f8 = fy3;
01296
01297
01298
01299 t1 = Build_TN_Of_Mtype(MTYPE_F8);
01300 Build_OP(TOP_fma_d, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f8, f0, ops);
01301 RESET_COND_DEF_LAST(ops);
01302 f9 = t1;
01303
01304
01305
01306 t1 = Build_TN_Of_Mtype(MTYPE_F8);
01307 Build_OP(TOP_fnma_d, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f6, ops);
01308 RESET_COND_DEF_LAST(ops);
01309 f6 = t1;
01310
01311
01312
01313 Build_OP(TOP_fma_d, fr, p6, Gen_Enum_TN(ECV_sf_s0), f6, f8, f9, ops);
01314 f8 = fr;
01315
01316 Exp_COPY(result, f8, ops);
01317 } else {
01318
01319
01320
01321
01322 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
01323 Build_OP(TOP_frcpa, result, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, f7, ops);
01324 }
01325 }
01326
01327
01328
01329
01330 static void
01331 Expand_F10_Div_By_Const(TN *result, TN *src1, TN *src2,
01332 const float_rf *b, OPS *ops)
01333 {
01334 INT pr;
01335 float_rf y0, y1, y2, y3, y4;
01336 float_rf e0, e1, e2, e3;
01337 TN * const f0 = FZero_TN;
01338 TN *f6 = src1;
01339 TN * const f7 = src2;
01340 TN *f8, *f9, *f10, *fr, *fy3, *fy4;
01341 TN * const p0 = True_TN;
01342 TN *p6;
01343 TN *t1;
01344 status_field sf[2] = {
01345 0x0000000000000300,
01346 0x0000000000001380,
01347 };
01348
01349
01350
01351
01352
01353
01354 y0 = frcpa(&pr, &One_rf, b, &sf[0]);
01355
01356
01357
01358 e0 = fnma(b, &y0, &One_rf, &sf[1]);
01359
01360
01361
01362 y1 = fma(&e0, &y0, &y0, &sf[1]);
01363
01364
01365
01366 e1 = fma(&e0, &e0, &Zero_rf, &sf[1]);
01367
01368
01369
01370 y2 = fma(&e1, &y1, &y1, &sf[1]);
01371
01372
01373
01374
01375 e2 = fnma(b, &y2, &One_rf, &sf[1]);
01376
01377
01378
01379 y3 = fma(&e2, &y2, &y2, &sf[1]);
01380
01381
01382
01383
01384 e3 = fnma(b, &y3, &One_rf, &sf[1]);
01385
01386
01387
01388 y4 = fma(&e3, &y3, &y3, &sf[1]);
01389
01390
01391
01392 if (pr) {
01393 fy3 = Build_TN_Of_Mtype(MTYPE_F10);
01394 Load_82bit_Constant(fy3, &y3, ops);
01395
01396 fy4 = Build_TN_Of_Mtype(MTYPE_F10);
01397 Load_82bit_Constant(fy4, &y4, ops);
01398
01399
01400
01401
01402 f8 = Build_TN_Of_Mtype(MTYPE_F10);
01403 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
01404 Build_OP(TOP_frcpa, f8, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, f7, ops);
01405 fr = f8;
01406
01407
01408
01409
01410
01411
01412
01413
01414 t1 = Build_TN_Of_Mtype(MTYPE_F10);
01415 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f6, f8, f0, ops);
01416 RESET_COND_DEF_LAST(ops);
01417 f10 = t1;
01418
01419
01420
01421 f8 = fy3;
01422
01423
01424
01425 t1 = Build_TN_Of_Mtype(MTYPE_F10);
01426 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f10, f6, ops);
01427 RESET_COND_DEF_LAST(ops);
01428 f9 = t1;
01429
01430
01431
01432 t1 = Build_TN_Of_Mtype(MTYPE_F10);
01433 Build_OP(TOP_fma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f9, f8, f10, ops);
01434 RESET_COND_DEF_LAST(ops);
01435 f9 = t1;
01436
01437
01438
01439 f8 = fy4;
01440
01441
01442
01443 t1 = Build_TN_Of_Mtype(MTYPE_F10);
01444 Build_OP(TOP_fnma, t1, p6, Gen_Enum_TN(ECV_sf_s1), f7, f9, f6, ops);
01445 RESET_COND_DEF_LAST(ops);
01446 f10 = t1;
01447
01448
01449
01450 Build_OP(TOP_fma, fr, p6, Gen_Enum_TN(ECV_sf_s0), f10, f8, f9, ops);
01451 f8 = fr;
01452
01453 Exp_COPY(result, f8, ops);
01454 } else {
01455
01456
01457
01458
01459 p6 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
01460 Build_OP(TOP_frcpa, result, p6, p0, Gen_Enum_TN(ECV_sf_s0), f6, f7, ops);
01461 }
01462 }
01463
01464
01465
01466
01467
01468
01469 static BOOL
01470 Expand_Float_Div_By_Pow2(TN *result, TN *src1, TCON src2, TYPE_ID mtype, OPS *ops)
01471 {
01472 TN *t1, *t2;
01473 TOP fmpy;
01474 INT exp;
01475 INT sign;
01476 INT32 sign_exp;
01477
01478
01479
01480
01481
01482
01483 switch (mtype) {
01484 case MTYPE_F4:
01485 {
01486 float val = TCON_fval(src2);
01487 UINT32 w = *(UINT32 *)&val;
01488 exp = ((w >> 23) & 0xff) - E32bias;
01489 sign = (w >> 31) & 0x1;
01490 fmpy = TOP_fmpy_s;
01491 }
01492 break;
01493 case MTYPE_F8:
01494 {
01495 double val = TCON_dval(src2);
01496 UINT64 dw = *(UINT64 *)&val;
01497 exp = ((dw >> 52) & 0x7ff) - E64bias;
01498 sign = (dw >> 63) & 0x1;
01499 fmpy = TOP_fmpy_d;
01500 }
01501 break;
01502 case MTYPE_F10:
01503 {
01504
01505 fmpy = TOP_fmpy;
01506 }
01507 return FALSE;
01508 }
01509
01510
01511
01512 if (exp == 0) {
01513 if (sign == 0) {
01514 Exp_COPY(result, src1, ops);
01515 } else {
01516 Expand_Neg(result, src1, mtype, ops);
01517 }
01518 return TRUE;
01519 }
01520
01521
01522
01523
01524 exp = -exp;
01525
01526
01527
01528 sign_exp = (sign << 17) | (exp + E82bias);
01529 t1 = Build_TN_Of_Mtype(MTYPE_I4);
01530 Build_OP(TOP_mov_i, t1, True_TN, Gen_Literal_TN(sign_exp, 4), ops);
01531 CGSPILL_Attach_Intconst_Remat(t1, sign_exp);
01532 t2 = Build_TN_Of_Mtype(mtype);
01533 Build_OP(TOP_setf_exp, t2, True_TN, t1, ops);
01534 CGSPILL_Attach_Floatconst_Remat(t2, mtype, 1.0 / Targ_To_Host_Float(src2));
01535
01536 Build_OP(fmpy, result, True_TN, Gen_Enum_TN(ECV_sf_s0), src1, t2, ops);
01537
01538 return TRUE;
01539 }
01540
01541
01542
01543
01544
01545
01546 static BOOL
01547 Expand_Float_Div_By_Const(TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01548 {
01549 INT Emin, Emax;
01550 INT sign;
01551 INT exp;
01552 UINT64 frac;
01553 float_rf b;
01554 WN *home;
01555 TCON tc;
01556
01557
01558
01559 home = TN_home(src2);
01560 if (WN_operator(home) != OPR_CONST) return FALSE;
01561 tc = ST_tcon_val(WN_st(home));
01562
01563 if ( Targ_Is_Power_Of_Two(tc)
01564 && Expand_Float_Div_By_Pow2(result, src1, tc, mtype, ops))
01565 {
01566 return TRUE;
01567 }
01568
01569
01570
01571
01572
01573
01574 switch (mtype) {
01575 case MTYPE_F4:
01576 {
01577 float val = TCON_fval(tc);
01578 UINT32 w = *(UINT32 *)&val;
01579 sign = (w >> 31) & 1;
01580 exp = ((w >> 23) & 0xff) - E32bias;
01581 frac = (UINT64)((w >> 0) & 0x7fffff) << 40;
01582 Emin = E32min;
01583 Emax = E32max;
01584 }
01585 break;
01586 case MTYPE_F8:
01587 {
01588 double val = TCON_dval(tc);
01589 UINT64 dw = *(UINT64 *)&val;
01590 sign = (dw >> 63) & 1;
01591 exp = ((dw >> 52) & 0x7ff) - E64bias;
01592 frac = ((dw >> 0) & 0xfffffffffffffULL) << 11;
01593 Emin = E64min;
01594 Emax = E64max;
01595 }
01596 break;
01597 case MTYPE_F10:
01598 {
01599 Emin = E80min;
01600 Emax = E80max;
01601 }
01602
01603 return FALSE;
01604 default:
01605 return FALSE;
01606 }
01607
01608
01609
01610 if (exp >= Emin && exp <= Emax) {
01611
01612 b.sign = sign;
01613 b.exp = exp + E82bias;
01614 b.frac = frac | (1ULL << 63);
01615 } else if (exp == Emin-1 && frac == 0) {
01616
01617 b.sign = sign;
01618 b.exp = E82min-1 + E82bias;
01619 b.frac = 0;
01620 } else if (exp == Emin-1 && frac != 0) {
01621
01622 b.sign = sign;
01623 b.exp = Emin + E82bias;
01624 b.frac = frac;
01625 } else if (exp == Emax+1 && frac == 0) {
01626
01627 b.sign = sign;
01628 b.exp = E82max+1 + E82bias;
01629 b.frac = 0;
01630 } else if (exp == Emax+1 && frac != 0) {
01631
01632
01633 return FALSE;
01634 } else {
01635 Is_True(FALSE, ("unable to classify %d %d 0x%016llx", sign, exp, frac));
01636 return FALSE;
01637 }
01638
01639
01640
01641 switch (mtype) {
01642 case MTYPE_F4:
01643 Expand_F4_Div_By_Const(result, src1, src2, &b, ops);
01644 break;
01645 case MTYPE_F8:
01646 Expand_F8_Div_By_Const(result, src1, src2, &b, ops);
01647 break;
01648 case MTYPE_F10:
01649 Expand_F10_Div_By_Const(result, src1, src2, &b, ops);
01650 break;
01651 }
01652
01653 return TRUE;
01654 }
01655
01656
01657
01658
01659
01660
01661
01662 void
01663 Expand_Float_Divide(TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
01664 {
01665 static BOOL initialized;
01666 static void (*f4div)(TN *, TN *, TN *, OPS *) = Expand_SGI_F4_Divide;
01667 static void (*f8div)(TN *, TN *, TN *, OPS *) = Expand_SGI_F8_Divide;
01668 static void (*f10div)(TN *, TN *, TN *, OPS *) = Expand_SGI_F10_Divide;
01669
01670
01671
01672 if (CGEXP_opt_float_div_by_const) {
01673 if (src2 == FOne_TN) {
01674 Exp_COPY(result, src1, ops);
01675 return;
01676 } else if ( TN_is_rematerializable(src2)
01677 && Expand_Float_Div_By_Const(result, src1, src2, mtype, ops))
01678 {
01679 return;
01680 }
01681 }
01682
01683 if (!initialized) {
01684 const char * const alg = CGEXP_fdiv_algorithm;
01685 if (strcasecmp(alg, "intel_max_thr") == 0) {
01686 f4div = Expand_Intel_Max_Thr_F4_Divide;
01687 f8div = Expand_Intel_Max_Thr_F8_Divide;
01688 f10div = Expand_Intel_Max_Thr_F10_Divide;
01689 } else if (strcasecmp(alg, "intel_min_lat") == 0) {
01690 f4div = Expand_Intel_Min_Lat_F4_Divide;
01691 f8div = Expand_Intel_Min_Lat_F8_Divide;
01692 f10div = Expand_Intel_Min_Lat_F10_Divide;
01693 } else if (strcasecmp(alg, "sgi") != 0) {
01694 DevWarn("invalid fdiv algorithm: %s", alg);
01695 }
01696 initialized = TRUE;
01697 }
01698
01699 switch (mtype) {
01700 case MTYPE_F4:
01701 f4div(result, src1, src2, ops);
01702 break;
01703 case MTYPE_F8:
01704 f8div(result, src1, src2, ops);
01705 break;
01706 case MTYPE_F10:
01707 f10div(result, src1, src2, ops);
01708 break;
01709 default:
01710 FmtAssert(FALSE, ("Bad type in Expand_Float_Divide"));
01711
01712 }
01713 }
01714
01715 void
01716 Expand_Float_Recip(TN *result, TN *src, TYPE_ID mtype, OPS *ops)
01717 {
01718
01719
01720
01721
01722 switch (mtype) {
01723 case MTYPE_F4:
01724 Expand_F4_Recip(result, src, ops);
01725 break;
01726 case MTYPE_F8:
01727 Expand_F8_Recip(result, src, ops);
01728 break;
01729 case MTYPE_F10:
01730 Expand_F10_Recip(result, src, ops);
01731 break;
01732 default:
01733 FmtAssert(FALSE, ("Bad type in Expand_Float_Recip"));
01734
01735 }
01736 }
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746 typedef enum {
01747 DIVCHK_RUNTIME,
01748 DIVCHK_BYZERO,
01749 DIVCHK_OVERFLOW
01750 } DIVCHK_STATUS;
01751
01752
01753
01754
01755
01756
01757
01758 static DIVCHK_STATUS
01759 Check_Divide (TN *numerator, TN *divisor, TYPE_ID mtype, OPS *ops)
01760 {
01761
01762
01763 BOOL div_zero_check = FALSE;
01764
01765 INT64 divisor_val;
01766 BOOL const_divisor = TN_Value_At_Op (divisor, NULL, &divisor_val);
01767 BOOL is_double = MTYPE_is_size_double(mtype);
01768
01769
01770
01771 if (const_divisor) {
01772 if (divisor_val == 0) {
01773 if (div_zero_check) {
01774 Build_OP (TOP_break, True_TN, Gen_Literal_TN(FPE_INTDIV, 4), ops);
01775 }
01776 return DIVCHK_BYZERO;
01777 }
01778 } else if (div_zero_check) {
01779 TN *p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01780 TN *p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01781 TOP opc = is_double ? TOP_cmp_eq : TOP_cmp4_eq;
01782 Build_OP (opc, p1, p2, True_TN, divisor, Zero_TN, ops);
01783 Build_OP (TOP_break, p1, Gen_Literal_TN(FPE_INTDIV, 4), ops);
01784 }
01785
01786
01787
01788 if (MTYPE_is_signed(mtype)) {
01789 INT64 numer_val;
01790 BOOL const_numer = TN_Value_At_Op (numerator, NULL, &numer_val);
01791 const INT64 minint_val = is_double ? INT64_MIN : INT32_MIN;
01792 const INT min_tn_size = is_double ? 8 : 4;
01793 if (const_divisor && const_numer) {
01794 if (numer_val == minint_val && divisor_val == -1) {
01795 if (DEBUG_Div_Oflow_Check) {
01796 Build_OP (TOP_break, True_TN, Gen_Literal_TN(FPE_INTOVF, 4), ops);
01797 }
01798 return DIVCHK_OVERFLOW;
01799 }
01800 } else if (DEBUG_Div_Oflow_Check) {
01801
01802
01803
01804 TOP opc;
01805 TN *p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01806 TN *p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01807 if (const_numer) {
01808 opc = is_double ? TOP_cmp_i_eq : TOP_cmp4_i_eq;
01809 Build_OP (opc, p1, p2, True_TN, Gen_Literal_TN(-1, 4), divisor, ops);
01810 } else if (const_divisor) {
01811 TN *minint = Build_TN_Of_Mtype (mtype);
01812 Expand_Immediate (minint, Gen_Literal_TN(minint_val, min_tn_size),
01813 TRUE, ops);
01814 opc = is_double ? TOP_cmp_eq : TOP_cmp4_eq;
01815 Build_OP (opc, p1, p2, True_TN, numerator, minint, ops);
01816 } else {
01817 opc = is_double ? TOP_cmp_i_eq_unc : TOP_cmp4_i_eq_unc;
01818 Build_OP (opc, p1, p2, True_TN, Gen_Literal_TN(-1, 4), divisor, ops);
01819
01820 TN *minint = Build_TN_Of_Mtype (mtype);
01821 Expand_Immediate (minint, Gen_Literal_TN(minint_val, min_tn_size),
01822 TRUE, ops);
01823 opc = is_double ? TOP_cmp_eq_and : TOP_cmp4_eq_and;
01824 Build_OP (opc, p1, p2, True_TN, numerator, minint, ops);
01825 }
01826 Build_OP (TOP_break, p1, Gen_Literal_TN(FPE_INTOVF, 4), ops);
01827 }
01828 }
01829
01830 return DIVCHK_RUNTIME;
01831 }
01832
01833
01834
01835 #define IS_POWER_OF_2(val) ((val != 0) && ((val & (val-1)) == 0))
01836
01837 static BOOL Is_Power_Of_2(INT64 val, TYPE_ID mtype)
01838 {
01839 if (MTYPE_is_signed(mtype) && val < 0) val = -val;
01840
01841 if (mtype == MTYPE_U4) val &= 0xffffffffull;
01842
01843 return IS_POWER_OF_2(val);
01844 }
01845
01846
01847 static INT
01848 Get_Power_Of_2 (INT64 val, TYPE_ID mtype)
01849 {
01850 INT i;
01851 INT64 pow2mask;
01852
01853 if (MTYPE_is_signed(mtype) && val < 0) val = -val;
01854
01855 if (mtype == MTYPE_U4) val &= 0xffffffffull;
01856
01857 pow2mask = 1;
01858 for ( i = 0; i < MTYPE_size_reg(mtype); ++i ) {
01859 if (val == pow2mask) return i;
01860 pow2mask <<= 1;
01861 }
01862
01863 FmtAssert(FALSE, ("Get_Power_Of_2 unexpected value"));
01864
01865 }
01866
01867
01868
01869
01870
01871 static void
01872 Expand_Power_Of_2_Divide (TN *result, TN *numer, INT64 dvsr, TYPE_ID mtype, OPS *ops)
01873 {
01874 INT n = Get_Power_Of_2(dvsr, mtype);
01875
01876 if (MTYPE_is_unsigned(mtype)) {
01877 Expand_Shift(result, numer, Gen_Literal_TN(n, 4), mtype, shift_lright, ops);
01878 } else {
01879 TN *t1 = Build_TN_Of_Mtype(mtype);
01880 TN *t2 = dvsr < 0 ? Build_TN_Of_Mtype(mtype) : result;
01881 INT64 absdvsr = dvsr < 0 ? -dvsr : dvsr;
01882 BOOL is_double = MTYPE_is_size_double(mtype);
01883 if (absdvsr == 2) {
01884
01885
01886
01887
01888
01889
01890
01891 TN *t0 = Build_TN_Of_Mtype(mtype);
01892 Build_OP(TOP_extr_u, t0, True_TN, numer,
01893 Gen_Literal_TN(is_double ? 63 : 31, 4),
01894 Gen_Literal_TN(1, 4), ops);
01895 Build_OP(TOP_add, t1, True_TN, t0, numer, ops);
01896 if (is_double) {
01897 Build_OP(TOP_shr_i, t2, True_TN, t1, Gen_Literal_TN(1, 4), ops);
01898 } else {
01899
01900
01901
01902 Build_OP(TOP_extr, t2, True_TN, t1,
01903 Gen_Literal_TN(1, 4), Gen_Literal_TN(31, 4), ops);
01904 }
01905 } else {
01906
01907
01908
01909
01910
01911
01912
01913
01914 TN *p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01915 TN *p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
01916 TOP opc = is_double ? TOP_cmp_lt : TOP_cmp4_lt;
01917 Build_OP(opc, p1, p2, True_TN, numer, Zero_TN, ops);
01918 Expand_Add (t1, Gen_Literal_TN(absdvsr-1, is_double ? 8 : 4),
01919 numer, mtype, ops);
01920 if (is_double) {
01921 Build_OP(TOP_shr_i, t2, p1, t1, Gen_Literal_TN(n, 4), ops);
01922 Build_OP(TOP_shr_i, t2, p2, numer, Gen_Literal_TN(n, 4), ops);
01923 } else {
01924
01925
01926
01927 Build_OP(TOP_extr, t2, p1, t1,
01928 Gen_Literal_TN(n, 4), Gen_Literal_TN(32-n, 4), ops);
01929 Build_OP(TOP_extr, t2, p2, numer,
01930 Gen_Literal_TN(n, 4), Gen_Literal_TN(32-n, 4), ops);
01931 }
01932 }
01933 if (dvsr < 0) Expand_Neg(result, t2, mtype, ops);
01934 }
01935 }
01936
01937 #ifdef OSP_OPT
01938
01939
01940 static void
01941 Expand_NonConst_DivRem (TN *quot, TN *rem, TN *x, TN *y, TYPE_ID mtype, OPS *ops)
01942 {
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966 INT i;
01967 TN *tn;
01968 TN *f2, *f2a, *f2b, *f3, *f4, *f6, *f12, *f13, *x_in_fp;
01969 BOOL is_recip;
01970 BOOL is_signed = MTYPE_is_signed(mtype);
01971 BOOL is_double = MTYPE_is_size_double(mtype) != 0;
01972 TN * const qp = True_TN;
01973 TOP fnma = TOP_fnma;
01974 TOP fma = TOP_fma;
01975 TOP fmpy = TOP_fmpy;
01976
01977
01978
01979 is_recip = FALSE;
01980 if (TN_is_rematerializable(x)) {
01981 INT64 x_val = WN_const_val(TN_home(x));
01982 if (x_val == 1) is_recip = TRUE;
01983 }
01984
01985
01986
01987 if (TN_has_value(y)) {
01988 TN *result = quot ? quot : rem;
01989 TN *tmp = Build_TN_Like(result);
01990 Expand_Immediate(tmp, y, is_signed, ops);
01991 y = tmp;
01992 }
01993
01994
01995 x_in_fp = f12 = Build_TN_Of_Mtype (MTYPE_F10);
01996 Build_OP(TOP_setf_sig, f12, qp, x, ops);
01997 tn = Build_TN_Of_Mtype (MTYPE_F8);
01998 if (is_signed) {
01999 Build_OP(TOP_fcvt_xf, tn, qp, f12, ops);
02000 } else {
02001 Build_OP(TOP_fcvt_xuf, tn, qp, Gen_Enum_TN(ECV_sf_s0), f12, ops);
02002 }
02003 f12 = tn;
02004
02005 f13 = Build_TN_Of_Mtype (MTYPE_F10);
02006 Build_OP(TOP_setf_sig, f13, qp, y, ops);
02007 tn = Build_TN_Of_Mtype (MTYPE_F10);
02008 if (is_signed) {
02009 Build_OP(TOP_fcvt_xf, tn, qp, f13, ops);
02010 } else {
02011 Build_OP(TOP_fcvt_xuf, tn, qp, Gen_Enum_TN(ECV_sf_s0), f13, ops);
02012 }
02013 f13 = tn;
02014
02015 f2 = Build_TN_Of_Mtype (MTYPE_F10);
02016 if (is_recip) {
02017
02018
02019
02020 TN * qpred = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
02021 tn = Build_TN_Of_Mtype (MTYPE_F10);
02022 Build_OP(TOP_frcpa, tn, qpred , qp, Gen_Enum_TN(ECV_sf_s0), f12, f13, ops);
02023 Build_OP(TOP_fma, f2, qpred , Gen_Enum_TN(ECV_sf_s1), tn, f12, tn, ops);
02024 } else {
02025 if (is_double) {
02026 if (mtype == MTYPE_I8)
02027 Expand_I8_I8_Divide(f2, f12, f13, ops);
02028 else
02029 Expand_SGI_F10_Divide(f2, f12, f13, ops);
02030 } else {
02031 if (mtype==MTYPE_I1 ||mtype==MTYPE_I2 || mtype==MTYPE_I4 || mtype==MTYPE_U1 ||mtype==MTYPE_U2||mtype==MTYPE_U4)
02032 {
02033 Expand_I4_I4_Divide(f2,f12,f13,ops);
02034 }
02035 else
02036 {
02037 Expand_SGI_F8_Divide(f2, f12, f13, ops);
02038 }
02039 }
02040 }
02041
02042 f2a = Build_TN_Of_Mtype (MTYPE_F10);
02043 Build_OP(is_signed ? TOP_fcvt_fx_trunc : TOP_fcvt_fxu_trunc,
02044 f2a, qp, Gen_Enum_TN(ECV_sf_s1), f2, ops);
02045
02046 if (rem) {
02047 TN *minus_y = Build_TN_Like (y);
02048 TN *minus_y_in_fp = Build_TN_Of_Mtype (MTYPE_F10);
02049 f3 = Build_TN_Of_Mtype (MTYPE_F10);
02050
02051 Build_OP(TOP_sub, minus_y, qp, Zero_TN, y, ops);
02052 Build_OP(TOP_setf_sig, minus_y_in_fp, qp, minus_y, ops);
02053 Build_OP(TOP_xma_l, f3, qp, f2a, minus_y_in_fp, x_in_fp, ops);
02054 Build_OP(TOP_getf_sig, rem, qp, f3, ops);
02055 }
02056
02057 if (quot) {
02058 Build_OP(TOP_getf_sig, quot, qp, f2a, ops);
02059 }
02060 }
02061 #endif
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112 static UINT64 determine_pseudo_inverse (
02113 UINT64 b,
02114 INT64 maxbits_a,
02115 INT64 *pn)
02116 {
02117 INT64 i, n;
02118 UINT64 m, q, b1;
02119
02120
02121
02122
02123
02124 b1 = b - 1;
02125 n = 1;
02126 m = 1;
02127 while(m < b1) {
02128 n++;
02129 m = (m<<1) | 1;
02130 }
02131 *pn = n;
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144 for(q=i=0; i<=maxbits_a; i++) {
02145 q <<= 1;
02146 if(m >= b) {
02147 m -= b;
02148 q |= 1;
02149 }
02150 m = (m<<1) | 1;
02151 }
02152 return 1+q;
02153 }
02154
02155
02156
02157
02158
02159 static BOOL
02160 Expand_Integer_Divide_By_Constant(TN *result, TN *numer_tn, INT64 denom_val,
02161 TYPE_ID mtype, OPS *ops)
02162 {
02163 UINT64 b;
02164 UINT64 d;
02165 INT64 precision_required;
02166 INT64 n;
02167 BOOL is_odd;
02168 TN *d_tn;
02169 TN *abs_tn;
02170 TN *mult_tn;
02171 TN *shift_tn;
02172 TOP opc;
02173 TN *p1, *p2;
02174 BOOL is_double = MTYPE_is_size_double(mtype);
02175 BOOL is_signed = MTYPE_is_signed(mtype);
02176
02177
02178
02179 if (denom_val == 1) {
02180 Exp_COPY(result, numer_tn, ops);
02181 return TRUE;
02182 } else if (is_signed && denom_val == -1) {
02183 Expand_Neg(result, numer_tn, mtype, ops);
02184 return TRUE;
02185 }
02186
02187
02188
02189 if (Is_Power_Of_2( denom_val, mtype)) {
02190 Expand_Power_Of_2_Divide(result, numer_tn, denom_val, mtype, ops);
02191 return TRUE;
02192 }
02193
02194 if (!CGEXP_cvrt_int_div_to_mult) return FALSE;
02195
02196 if (is_signed) {
02197
02198 b = denom_val<0 ? -denom_val : denom_val;
02199 is_odd = (b&1);
02200
02201 d = determine_pseudo_inverse (b, is_double ? 63 : 31, &n);
02202
02203 if (n > (is_double ? 63 : 31)) {
02204
02205 return FALSE;
02206 }
02207
02208 d_tn = Build_TN_Like (result);
02209 Expand_Immediate (d_tn,
02210 Gen_Literal_TN (is_double ? d : d << 32, 8),
02211 is_signed, ops);
02212
02213
02214
02215 abs_tn = Build_TN_Of_Mtype (mtype);
02216 p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
02217 p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
02218 opc = is_double ? TOP_cmp_lt : TOP_cmp4_lt;
02219 Build_OP (opc, p1, p2, True_TN, numer_tn, Zero_TN, ops);
02220 Build_OP (TOP_sub, abs_tn, p1, Zero_TN, numer_tn, ops);
02221 Build_OP (TOP_mov, abs_tn, p2, numer_tn, ops);
02222
02223
02224
02225 mult_tn = Build_TN_Of_Mtype (mtype);
02226 Expand_High_Multiply (mult_tn, abs_tn, d_tn, MTYPE_U8, ops);
02227
02228
02229
02230 if (n > 0) {
02231 shift_tn = Build_TN_Of_Mtype (mtype);
02232 Build_OP (TOP_shr_i_u, shift_tn, True_TN, mult_tn, Gen_Literal_TN (n-1, 4), ops);
02233 } else {
02234 shift_tn = mult_tn;
02235 }
02236
02237
02238
02239 if (denom_val < 0) {
02240 TN *tmp = p1;
02241 p1 = p2;
02242 p2 = tmp;
02243 }
02244 Build_OP (TOP_sub, result, p1, Zero_TN, shift_tn, ops);
02245 Build_OP (TOP_mov, result, p2, shift_tn, ops);
02246 }
02247
02248 else {
02249
02250 b = denom_val;
02251 is_odd = (b&1);
02252
02253
02254
02255 if (is_double) {
02256 if (is_odd) {
02257 precision_required = 64;
02258 } else {
02259
02260
02261
02262
02263
02264 b >>= 1;
02265 precision_required = 63;
02266
02267
02268
02269 TN *tmp1_tn = Build_TN_Of_Mtype (mtype);
02270 Build_OP (TOP_shr_i_u, tmp1_tn, True_TN, numer_tn, Gen_Literal_TN (1, 4), ops);
02271 numer_tn = tmp1_tn;
02272 }
02273 } else{
02274 precision_required = 63;
02275 }
02276
02277 d = determine_pseudo_inverse (b, precision_required, &n);
02278
02279 if (n > precision_required) {
02280
02281 return FALSE;
02282 }
02283
02284 d_tn = Build_TN_Like (result);
02285
02286 Expand_Immediate (d_tn, Gen_Literal_TN (d, 8), is_signed, ops);
02287
02288
02289
02290 mult_tn = Build_TN_Of_Mtype (mtype);
02291
02292 Expand_High_Multiply (mult_tn, numer_tn, d_tn, MTYPE_U8, ops);
02293
02294 if (precision_required == 64) {
02295
02296
02297
02298 TN *tmp1_tn = Build_TN_Of_Mtype (mtype);
02299 TN *tmp2_tn = Build_TN_Of_Mtype (mtype);
02300 TN *tmp3_tn = Build_TN_Of_Mtype (mtype);
02301 Build_OP (TOP_sub, tmp1_tn, True_TN, numer_tn, mult_tn, ops);
02302 Build_OP (TOP_shr_i_u, tmp2_tn, True_TN, tmp1_tn, Gen_Literal_TN (1, 4), ops);
02303 Build_OP (TOP_add, tmp3_tn, True_TN, mult_tn, tmp2_tn, ops);
02304 mult_tn = tmp3_tn;
02305 }
02306
02307
02308
02309 Build_OP (TOP_shr_i_u, result, True_TN, mult_tn,
02310 Gen_Literal_TN (n-1, 4),
02311 ops);
02312
02313 }
02314
02315 return TRUE;
02316 }
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335 static void
02336 Expand_Power_Of_2_Rem (TN *result, TN *src1, INT64 src2_val, TYPE_ID mtype, OPS *ops)
02337 {
02338 BOOL is_double = MTYPE_is_size_double(mtype);
02339 INT n = Get_Power_Of_2(src2_val, mtype);
02340 INT64 nMask = (1LL << n) - 1;
02341 TN *con = Gen_Literal_TN(nMask, is_double ? 8 : 4);
02342
02343 if (MTYPE_is_signed(mtype)) {
02344 TN *tmp1, *tmp2;
02345 TN *p1, *p2;
02346 TOP opc;
02347
02348
02349
02350 p1 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
02351 p2 = Build_RCLASS_TN (ISA_REGISTER_CLASS_predicate);
02352 opc = is_double ? TOP_cmp_lt : TOP_cmp4_lt;
02353 Build_OP(opc, p1, p2, True_TN, src1, Zero_TN, ops);
02354
02355
02356
02357 tmp1 = Build_TN_Of_Mtype(mtype);
02358 Build_OP(TOP_sub, tmp1, p1, Zero_TN, src1, ops);
02359 Build_OP(TOP_mov, tmp1, p2, src1, ops);
02360
02361
02362
02363 tmp2 = Build_TN_Of_Mtype(mtype);
02364 Expand_Binary_And(tmp2, tmp1, con, mtype, ops);
02365
02366
02367
02368 Build_OP(TOP_sub, result, p1, Zero_TN, tmp2, ops);
02369 Build_OP(TOP_mov, result, p2, tmp2, ops);
02370 } else {
02371 Expand_Binary_And(result, src1, con, mtype, ops);
02372 }
02373 }
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390 static void
02391 Expand_Power_Of_2_Mod (TN *result, TN *src1, INT64 src2_val, TYPE_ID mtype, OPS *ops)
02392 {
02393 BOOL is_double = MTYPE_is_size_double(mtype);
02394 INT64 absval = src2_val < 0 ? -src2_val : src2_val;
02395 INT n = Get_Power_Of_2(absval, mtype);
02396 INT64 nMask = (1LL << n) - 1;
02397 TN *con = Gen_Literal_TN(nMask, is_double ? 8 : 4);
02398
02399 if (MTYPE_is_signed(mtype) && src2_val < 0) {
02400 TN *tmp1, *tmp2;
02401
02402 tmp1 = Build_TN_Of_Mtype(mtype);
02403 Expand_Neg(tmp1, src1, mtype, ops);
02404
02405 tmp2 = Build_TN_Of_Mtype(mtype);
02406 Expand_Binary_And(tmp2, tmp1, con, mtype, ops);
02407
02408 Expand_Neg(result, tmp2, mtype, ops);
02409 } else {
02410 Expand_Binary_And(result, src1, con, mtype, ops);
02411 }
02412 }
02413
02414
02415
02416
02417
02418
02419
02420 TN *
02421 Expand_Divide (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops)
02422 {
02423
02424
02425
02426 switch (Check_Divide(src1, src2, mtype, ops)) {
02427 case DIVCHK_BYZERO:
02428 case DIVCHK_OVERFLOW:
02429 Build_OP(TOP_ifixup, result, ops);
02430 return NULL;
02431 }
02432
02433
02434
02435 INT64 src2_val;
02436 BOOL const_src2 = TN_Value_At_Op (src2, NULL, &src2_val);
02437 if (const_src2) {
02438 if (Expand_Integer_Divide_By_Constant(result, src1, src2_val, mtype, ops)) {
02439 return NULL;
02440 }
02441 }
02442
02443 Expand_NonConst_DivRem(result, NULL, src1, src2, mtype, ops);
02444 return NULL;
02445 }
02446
02447
02448 void
02449 Expand_Rem (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops, OPCODE opcode)
02450 {
02451
02452
02453
02454 switch (Check_Divide(src1, src2, mtype, ops)) {
02455 case DIVCHK_BYZERO:
02456 case DIVCHK_OVERFLOW:
02457 Build_OP(TOP_ifixup, result, ops);
02458 return;
02459 }
02460
02461
02462
02463 INT64 src2_val;
02464 BOOL const_src2 = TN_Value_At_Op (src2, NULL, &src2_val);
02465 if (const_src2) {
02466
02467
02468
02469 if (Is_Power_Of_2(src2_val, mtype)) {
02470 Expand_Power_Of_2_Rem(result, src1, src2_val, mtype, ops);
02471 return;
02472 }
02473
02474 if (CGEXP_cvrt_int_div_to_mult) {
02475 TN *div_tn = Build_TN_Like (result);
02476
02477 if (Expand_Integer_Divide_By_Constant(div_tn, src1, src2_val, mtype, ops)) {
02478 TN *mult_tn;
02479
02480
02481
02482 mult_tn = Build_TN_Like (result);
02483 Expand_Multiply(mult_tn, div_tn, src2, mtype, ops, opcode);
02484
02485
02486
02487 Build_OP(TOP_sub, result, True_TN, src1, mult_tn, ops);
02488 return;
02489 }
02490 }
02491 }
02492
02493 Expand_NonConst_DivRem(NULL, result, src1, src2, mtype, ops);
02494 }
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504 void
02505 Expand_Mod (TN *result, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops, OPCODE opcode)
02506 {
02507 TN *tmp1;
02508 TN *tmp2;
02509 TN *p1;
02510 TN *p2;
02511 TOP opc;
02512 BOOL is_double = MTYPE_is_size_double(mtype);
02513
02514
02515
02516
02517 switch (Check_Divide(src1, src2, mtype, ops)) {
02518 case DIVCHK_BYZERO:
02519 case DIVCHK_OVERFLOW:
02520 Build_OP(TOP_ifixup, result, ops);
02521 return;
02522 }
02523
02524
02525
02526 INT64 src2_val;
02527 BOOL const_src2 = TN_Value_At_Op (src2, NULL, &src2_val);
02528 if (const_src2 && Is_Power_Of_2(src2_val, mtype)) {
02529 Expand_Power_Of_2_Mod (result, src1, src2_val, mtype, ops);
02530 return;
02531 }
02532
02533
02534
02535 tmp1 = Build_TN_Like(result);
02536 Expand_Rem(tmp1, src1, src2, mtype, ops, opcode);
02537
02538
02539
02540 tmp2 = Build_TN_Like(result);
02541 Build_OP(TOP_xor, tmp2, True_TN, tmp1, src2, ops);
02542
02543 p1 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
02544 p2 = Build_RCLASS_TN(ISA_REGISTER_CLASS_predicate);
02545 opc = is_double ? TOP_cmp_lt : TOP_cmp4_lt;
02546 Build_OP(opc, p1, p2, True_TN, tmp2, Zero_TN, ops);
02547
02548
02549
02550
02551 Build_OP(TOP_add, result, p1, src2, tmp1, ops);
02552 Build_OP(TOP_mov, result, p2, tmp1, ops);
02553 }
02554
02555
02556 void
02557 Expand_DivRem(TN *result, TN *result2, TN *src1, TN *src2, TYPE_ID mtype, OPS *ops, OPCODE opcode)
02558 {
02559
02560
02561
02562 switch (Check_Divide(src1, src2, mtype, ops)) {
02563 case DIVCHK_BYZERO:
02564 case DIVCHK_OVERFLOW:
02565 Build_OP(TOP_ifixup, result, ops);
02566 Build_OP(TOP_ifixup, result2, ops);
02567 return;
02568 }
02569
02570
02571
02572
02573
02574
02575
02576 INT64 src1_val;
02577 BOOL const_src1 = TN_Value_At_Op (src1, NULL, &src1_val);
02578 INT64 src2_val;
02579 BOOL const_src2 = TN_Value_At_Op (src2, NULL, &src2_val);
02580 if (const_src1 && const_src2) {
02581 INT64 quot_val, rem_val;
02582 switch (mtype) {
02583 case MTYPE_I8:
02584 quot_val = (INT64)src1_val / (INT64)src2_val;
02585 rem_val = (INT64)src1_val % (INT64)src2_val;
02586 break;
02587 case MTYPE_U8:
02588 quot_val = (UINT64)src1_val / (UINT64)src2_val;
02589 rem_val = (UINT64)src1_val % (UINT64)src2_val;
02590 break;
02591 case MTYPE_U4:
02592 quot_val = (UINT32)src1_val / (UINT32)src2_val;
02593 rem_val = (UINT32)src1_val % (UINT32)src2_val;
02594 break;
02595 case MTYPE_I4:
02596 quot_val = (INT32)src1_val / (INT32)src2_val;
02597 rem_val = (INT32)src1_val % (INT32)src2_val;
02598 break;
02599 }
02600 BOOL is_signed = MTYPE_is_signed(mtype);
02601 INT tn_size = MTYPE_is_size_double(mtype) ? 8 : 4;
02602 Exp_Immediate(result, Gen_Literal_TN(quot_val, tn_size), is_signed, ops);
02603 Exp_Immediate(result2, Gen_Literal_TN(rem_val, tn_size), is_signed, ops);
02604 return;
02605 }
02606
02607
02608
02609 if (const_src2) {
02610 if (Expand_Integer_Divide_By_Constant(result, src1, src2_val, mtype, ops)) {
02611
02612
02613
02614
02615
02616 if (!MTYPE_is_signed(mtype) && Is_Power_Of_2(src2_val, mtype)) {
02617 Expand_Power_Of_2_Rem(result2, src1, src2_val, mtype, ops);
02618 } else {
02619 TN *t1 = Build_TN_Like(result);
02620 Expand_Multiply(t1, result, src2, mtype, ops, opcode);
02621 Build_OP(TOP_sub, result2, True_TN, src1, t1, ops);
02622 }
02623 return;
02624 }
02625 }
02626 Expand_NonConst_DivRem(result, result2, src1, src2, mtype, ops);
02627 }