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 #include "elf_stuff.h"
00042 #include <vector>
00043 #include "defs.h"
00044 #include "em_elf.h"
00045 #include "erglob.h"
00046 #include "ercg.h"
00047 #include "tracing.h"
00048 #include "config.h"
00049 #include "config_targ_opt.h"
00050 #include "config_debug.h"
00051 #include "xstats.h"
00052 #include "topcode.h"
00053 #include "tn.h"
00054 #include "cg_flags.h"
00055 #include "targ_isa_lits.h"
00056 #include "op.h"
00057 #include "stblock.h"
00058 #include "data_layout.h"
00059 #include "strtab.h"
00060 #include "symtab.h"
00061 #include "cg.h"
00062 #include "cgexp.h"
00063 #include "cgexp_internals.h"
00064 #include "cgemit.h"
00065
00066 #define OFFSET_HI(offset) ((((offset) + 0x8000) >> 16) << 16)
00067 #define OFFSET_LO(offset) ((((offset) + 0x8000) & 0xffff) - 0x8000)
00068
00069 void
00070 Expand_Lda (TN *dest, TN *src, OPS *ops)
00071 {
00072 FmtAssert(FALSE, ("NYI: Expand_Lda"));
00073 }
00074
00075 static TOP
00076 Pick_Load_Instruction (TYPE_ID rtype, TYPE_ID desc)
00077 {
00078 switch (desc) {
00079 case MTYPE_I1: return TOP_lb;
00080 case MTYPE_U1: return TOP_lbu;
00081 case MTYPE_I2: return TOP_lh;
00082 case MTYPE_U2: return TOP_lhu;
00083 case MTYPE_I4: return TOP_lw;
00084 case MTYPE_U4: return MTYPE_is_size_double(rtype) ? TOP_lwu : TOP_lw;
00085 case MTYPE_I8: case MTYPE_U8: return TOP_ld;
00086 case MTYPE_F4: return TOP_lwc1;
00087 case MTYPE_F8: return TOP_ldc1;
00088
00089 case MTYPE_V:
00090 if (rtype != MTYPE_V)
00091
00092 return Pick_Load_Instruction(rtype,rtype);
00093
00094 default:
00095 FmtAssert(FALSE, ("NYI: Pick_Load_Instruction mtype"));
00096 return TOP_UNDEFINED;
00097 }
00098 }
00099
00100 #if defined(TARG_SL)
00101
00102 #define max_ofst 31
00103
00104 BOOL
00105 Expand_V1buf_Ldst(TOP top, TN* value, TN* base, TN* ofst, BOOL is_load, OPS* ops)
00106 {
00107
00108
00109
00110 if(is_load) {
00111 if(TN_is_symbol(ofst)) {
00112 INT64 ofst_val;
00113 ST* st = TN_var(ofst);
00114 ofst_val = TN_value(ofst);
00115 if(ST_in_v1buf(st)) {
00116 ofst = Gen_Symbol_TN(st, ofst_val,
00117 TN_RELOC_GPREL_SL2_V15);
00118 if(top == TOP_lbu)
00119 top = TOP_c2_ldi_v2g_b_u;
00120 else if(top == TOP_lb)
00121 top = TOP_c2_ldi_v2g_b;
00122 else
00123 Fail_FmtAssertion("no lbu/lb found");
00124 Build_OP(top, value, ofst, ops);
00125 return TRUE;
00126 }
00127 }
00128 else if(TN_is_v1buf_addr(base)) {
00129 if(top == TOP_lbu)
00130 top = TOP_c2_ld_v2g_b_u;
00131 else if(top == TOP_lb)
00132 top = TOP_c2_ld_v2g_b;
00133 else
00134 Fail_FmtAssertion("no lbu/lb found");
00135
00136 if(TN_value(ofst) > max_ofst) {
00137 Build_OP(TOP_addiu, base, base, ofst, ops);
00138 ofst = Gen_Literal_TN(0, 4);
00139 }
00140 Build_OP(top, value, base, ofst, ops);
00141 return TRUE;
00142 }
00143 }
00144 else {
00145
00146
00147 if(TN_is_symbol(ofst)) {
00148 INT64 ofst_val;
00149 ST* st = TN_var(ofst);
00150 ofst_val = TN_value(ofst);
00151 if(ST_in_v1buf(st)) {
00152 ofst = Gen_Symbol_TN(st, ofst_val,
00153 TN_RELOC_GPREL_SL2_V15);
00154 Build_OP(TOP_c2_sti_g2v_b, value, ofst, ops);
00155 return TRUE;
00156 }
00157 }
00158 else if (TN_is_v1buf_addr(base)) {
00159 if(TN_value(ofst) > max_ofst) {
00160 Build_OP(TOP_addiu, base, base, ofst, ops);
00161 ofst = Gen_Literal_TN(0, 4);
00162 }
00163 Build_OP(TOP_c2_st_g2v_b, value, base, ofst, ops);
00164 return TRUE;
00165 }
00166 }
00167 return FALSE;
00168 }
00169 #endif
00170
00171 void
00172 Expand_Load (OPCODE opcode, TN *result, TN *base, TN *ofst, OPS *ops)
00173 {
00174 TYPE_ID mtype = OPCODE_desc(opcode);
00175 TOP top = Pick_Load_Instruction (OPCODE_rtype(opcode), mtype);
00176 Is_True (TN_is_constant(ofst), ("Expand_Load: Illegal offset TN"));
00177
00178
00179
00180 if (TN_is_rematerializable(base) &&
00181 (!ISA_LC_Value_In_Class(TN_value(ofst), LC_simm16))) {
00182 WN *home = TN_home(base);
00183 if (WN_operator(home) == OPR_INTCONST) {
00184 INT64 val = WN_const_val(home);
00185 BOOL is_double = TN_size(base) == 8;
00186 TN *tmp_base = Gen_Literal_TN (val + TN_value(ofst), TN_size(base));
00187 tmp_base = Expand_Immediate_Into_Register(tmp_base, is_double, ops);
00188 Build_OP (top, result, tmp_base, Gen_Literal_TN (0, 2), ops);
00189 return;
00190 }
00191 }
00192 #if defined(TARG_SL)
00193 if(CG_sl2 && CG_SL2_enable_v1buf_expansion &&
00194 Expand_V1buf_Ldst(top, result, base, ofst, TRUE, ops)) return;
00195 #endif
00196 Build_OP (top, result, base, ofst, ops);
00197 }
00198
00199 static TOP
00200 Pick_Store_Instruction (TYPE_ID mtype)
00201 {
00202 switch (mtype) {
00203 case MTYPE_I1: case MTYPE_U1: return TOP_sb;
00204 case MTYPE_I2: case MTYPE_U2: return TOP_sh;
00205 case MTYPE_I4: case MTYPE_U4: return TOP_sw;
00206 case MTYPE_I8: case MTYPE_U8: return TOP_sd;
00207 case MTYPE_F4: return TOP_swc1;
00208 case MTYPE_F8: return TOP_sdc1;
00209 default: FmtAssert(FALSE, ("NYI: Pick_Store_Instruction mtype"));
00210 return TOP_UNDEFINED;
00211 }
00212 }
00213
00214 void
00215 Expand_Store (TYPE_ID mtype, TN *src, TN *base, TN *ofst, OPS *ops)
00216 {
00217 TOP top = Pick_Store_Instruction (mtype);
00218 Is_True (TN_is_constant(ofst), ("Expand_Store: Illegal offset TN"));
00219
00220 #if defined(TARG_SL)
00221 if(CG_sl2 && CG_SL2_enable_v1buf_expansion &&
00222 Expand_V1buf_Ldst(top, src, base, ofst, FALSE, ops)) return;
00223 #endif
00224 if (!TN_has_value(ofst) || ISA_LC_Value_In_Class(TN_value(ofst), LC_simm16))
00225 Build_OP (top, src, base, ofst, ops);
00226 else {
00227 TN *tmp_tn = Build_TN_Of_Mtype(Pointer_Mtype);
00228 INT32 tmp = TN_value(ofst) >> 16;
00229 if (tmp < 0) {
00230
00231 if (Use_32_Bit_Pointers)
00232 tmp &= 0xffff;
00233 }
00234 Build_OP(TOP_lui, tmp_tn, Gen_Literal_TN(tmp, 4), ops);
00235 Build_OP(Use_32_Bit_Pointers ? TOP_addu : TOP_daddu, tmp_tn,
00236 tmp_tn, base, ops);
00237 Build_OP(top, src, tmp_tn, Gen_Literal_TN(TN_value(ofst)&0xffff, 4), ops);
00238 }
00239 }
00240
00241 static OPCODE
00242 OPCODE_make_signed_op(OPERATOR op, TYPE_ID rtype, TYPE_ID desc, BOOL is_signed)
00243 {
00244 if (MTYPE_is_signed(rtype) != is_signed)
00245 rtype = MTYPE_complement(rtype);
00246 if (MTYPE_is_signed(desc) != is_signed)
00247 desc = MTYPE_complement(desc);
00248
00249 return OPCODE_make_op(op, rtype, desc);
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 static void
00266 Adjust_Addr_TNs (
00267 TOP opcode,
00268 TN **base_tn,
00269 TN **disp_tn,
00270 INT16 disp,
00271 OPS *ops)
00272 {
00273
00274 if ( Potential_Immediate_TN_Expr (opcode, *disp_tn, disp) )
00275 {
00276 if ( TN_has_value(*disp_tn) ) {
00277 *disp_tn = Gen_Literal_TN ( TN_value(*disp_tn) + disp, 4 );
00278 } else {
00279 *disp_tn = Gen_Symbol_TN ( TN_var(*disp_tn),
00280 TN_offset(*disp_tn) + disp, 0);
00281 }
00282 } else {
00283 TN *tmp = Build_TN_Of_Mtype (Pointer_Mtype);
00284
00285
00286 Expand_Add (tmp, *disp_tn, *base_tn, Pointer_Mtype, ops);
00287 *base_tn = tmp;
00288 *disp_tn = Gen_Literal_TN (disp, 4);
00289 }
00290 }
00291
00292 #ifdef TARG_SL
00293 static void
00294 Expand_Composed_Load ( OPCODE op, TN *result, TN *base, TN *disp, VARIANT variant, OPS *ops)
00295 {
00296 TYPE_ID rtype= OPCODE_rtype(op);
00297 TYPE_ID desc = OPCODE_desc(op);
00298 DevWarn ("Expand_Composed_Load: Unaligned load found");
00299 if (MTYPE_is_float(rtype)) {
00300 TN *load;
00301 DevWarn ("Float type in Expand_Composed_Load");
00302 if (rtype == MTYPE_F4) {
00303 load = Build_TN_Of_Mtype(MTYPE_I4);
00304 Expand_Composed_Load ( OPC_I4I4LDID, load, base, disp, variant, ops);
00305
00306 Build_OP ( TOP_mtc1, result, load, ops );
00307 } else {
00308 load = Build_TN_Of_Mtype(MTYPE_I8);
00309 Expand_Composed_Load ( OPC_I8I8LDID, load, base, disp, variant, ops);
00310 Build_OP ( TOP_dmtc1, result, load, ops );
00311 }
00312 Reset_TN_is_fpu_int(result);
00313 return;
00314 }
00315 else {
00316 TN *load1 = Build_TN_Of_Mtype(MTYPE_I4);
00317 TN *load2 = Build_TN_Of_Mtype(MTYPE_I4);
00318 TN *load3 = Build_TN_Of_Mtype(MTYPE_I4);
00319 TN *newbase = Build_TN_Of_Mtype(MTYPE_I4);
00320 switch (desc) {
00321 case MTYPE_I8:
00322 case MTYPE_U8:
00323 FmtAssert (FALSE, ("Expand_Composed_Load: 64bits data\n"));
00324 return;
00325 case MTYPE_I4:
00326 case MTYPE_U4:
00327 Build_OP (TOP_lbu, result, base, disp, ops);
00328
00329 Expand_Add (newbase, base, disp, MTYPE_I4, ops);
00330 Build_OP (TOP_lbu, load1, newbase, Gen_Literal_TN(1, 4), ops);
00331 Build_OP(TOP_depb, result, result, load1, Gen_Literal_TN(15, 4), Gen_Literal_TN(8, 4), ops);
00332
00333 Build_OP (TOP_lbu, load2, newbase, Gen_Literal_TN(2, 4), ops);
00334 Build_OP(TOP_depb, result, result, load2, Gen_Literal_TN(23, 4), Gen_Literal_TN(8, 4), ops);
00335
00336 Build_OP (TOP_lbu, load3, newbase, Gen_Literal_TN(3, 4), ops);
00337 Build_OP(TOP_depb, result, result, load3, Gen_Literal_TN(31, 4), Gen_Literal_TN(8, 4), ops);
00338
00339
00340 return;
00341 case MTYPE_I2:
00342 case MTYPE_U2:
00343 Build_OP (TOP_lbu, result, base, disp, ops);
00344
00345 Expand_Add (newbase, base, disp, MTYPE_I4, ops);
00346 Build_OP (TOP_lbu, load1, newbase, Gen_Literal_TN(1, 4), ops);
00347 Build_OP(TOP_depb, result, result, load1, Gen_Literal_TN(15, 4), Gen_Literal_TN(8, 4), ops);
00348 return;
00349 default:
00350 FmtAssert (FALSE, ("Expand_Composed_Load: unexpected operand size\n"));
00351 }
00352 }
00353 }
00354 #else
00355 static void
00356 Expand_Composed_Load ( OPCODE op, TN *result, TN *base, TN *disp, VARIANT variant, OPS *ops)
00357 {
00358 TYPE_ID rtype= OPCODE_rtype(op);
00359 TYPE_ID desc = OPCODE_desc(op);
00360 TN *tmp;
00361
00362 if (MTYPE_is_float(rtype)) {
00363 TN *load;
00364
00365 if (rtype == MTYPE_F4) {
00366 load = Build_TN_Of_Mtype(MTYPE_I4);
00367 Expand_Composed_Load ( OPC_I4I4LDID, load, base, disp, variant, ops);
00368
00369 Build_OP ( TOP_mtc1, result, load, ops );
00370 } else {
00371 load = Build_TN_Of_Mtype(MTYPE_I8);
00372 Expand_Composed_Load ( OPC_I8I8LDID, load, base, disp, variant, ops);
00373 Build_OP ( TOP_dmtc1, result, load, ops );
00374 }
00375 Reset_TN_is_fpu_int(result);
00376 return;
00377 }
00378
00379 switch (desc) {
00380 case MTYPE_I8:
00381 case MTYPE_U8:
00382 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_ldl : TOP_ldr,
00383 result, base, disp, ops);
00384
00385 Adjust_Addr_TNs (Target_Byte_Sex == BIG_ENDIAN ? TOP_ldr : TOP_ldl,
00386 &base, &disp, 7, ops);
00387 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_ldr : TOP_ldl,
00388 result, base, disp, ops);
00389 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
00390 return;
00391 case MTYPE_I4:
00392 case MTYPE_U4:
00393 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_lwl : TOP_lwr,
00394 result, base, disp, ops);
00395
00396 Adjust_Addr_TNs (Target_Byte_Sex == BIG_ENDIAN ? TOP_lwr : TOP_lwl,
00397 &base, &disp, 3, ops);
00398 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_lwr : TOP_lwl,
00399 result, base, disp, ops);
00400 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
00401
00402 if ((rtype == MTYPE_U8) && (desc == MTYPE_U4)) {
00403 Build_OP (TOP_dsll32, result, result, Gen_Literal_TN(0, 4), ops);
00404 Build_OP (TOP_dsrl32, result, result, Gen_Literal_TN(0, 4), ops);
00405 }
00406 return;
00407 case MTYPE_I2:
00408 case MTYPE_U2:
00409 if (Target_Byte_Sex == BIG_ENDIAN) {
00410 Build_OP (desc == MTYPE_I2 ? TOP_lb : TOP_lbu,
00411 result, base, disp, ops);
00412 Build_OP (TOP_sll, result, result, Gen_Literal_TN(8, 4), ops);
00413
00414 Adjust_Addr_TNs (TOP_lb, &base, &disp, 1, ops);
00415 tmp = Build_TN_Of_Mtype(rtype);
00416 Build_OP (TOP_lbu, tmp, base, disp, ops);
00417 Build_OP (TOP_or, result, result, tmp, ops);
00418 } else {
00419 tmp = Build_TN_Of_Mtype(rtype);
00420 Build_OP (TOP_lbu, tmp, base, disp, ops);
00421
00422 Adjust_Addr_TNs (TOP_lb, &base, &disp, 1, ops);
00423 Build_OP (desc == MTYPE_I2 ? TOP_lb : TOP_lbu,
00424 result, base, disp, ops);
00425 Build_OP (TOP_sll, result, result, Gen_Literal_TN(8, 4), ops);
00426 Build_OP (TOP_or, result, result, tmp, ops);
00427 }
00428 return;
00429 default:
00430 FmtAssert (FALSE, ("Expand_Composed_Load: unexpected operand size\n"));
00431 }
00432 }
00433 #endif
00434
00435 void
00436 Expand_Misaligned_Load ( OPCODE op, TN *result, TN *base, TN *disp, VARIANT variant, OPS *ops)
00437 {
00438 Expand_Composed_Load ( op, result, base, disp, variant, ops);
00439 }
00440
00441 #ifdef TARG_SL
00442 void
00443 Expand_Composed_Store (TYPE_ID mtype, TN *obj, TN *base, TN *disp, VARIANT variant, OPS *ops)
00444 {
00445 DevWarn ("Expand_Composed_Store: Unaligned store found");
00446 if (MTYPE_is_float(mtype))
00447 {
00448 TN *tmp;
00449 DevWarn ("Float type in Expand_Composed_Load");
00450 if (mtype == MTYPE_F4)
00451 {
00452 tmp = Build_TN_Of_Mtype(MTYPE_I4);
00453 Build_OP ( TOP_mfc1, tmp, obj, ops );
00454 Expand_Composed_Store (MTYPE_I4, tmp, base, disp, variant, ops);
00455 }
00456 else
00457 {
00458 tmp = Build_TN_Of_Mtype(MTYPE_I8);
00459 Build_OP ( TOP_dmfc1, tmp, obj, ops );
00460 Expand_Composed_Store (MTYPE_I8, tmp, base, disp, variant, ops);
00461 }
00462 return;
00463 }
00464
00465 else {
00466 TN *store1 = Build_TN_Of_Mtype(MTYPE_I4);
00467 TN *store2 = Build_TN_Of_Mtype(MTYPE_I4);
00468 TN *store3 = Build_TN_Of_Mtype(MTYPE_I4);
00469 TN *newbase = Build_TN_Of_Mtype(MTYPE_I4);
00470 switch (mtype) {
00471 case MTYPE_I8:
00472 case MTYPE_U8:
00473 FmtAssert (FALSE, ("Expand_Composed_Store: 64bits data\n"));
00474 return;
00475 case MTYPE_I4:
00476 case MTYPE_U4:
00477 Build_OP (TOP_sb, obj, base, disp, ops);
00478
00479 Expand_Add (newbase, base, disp, MTYPE_I4, ops);
00480 Build_OP(TOP_extrbu, store1, obj, Gen_Literal_TN(15, 4), Gen_Literal_TN(8, 4), ops);
00481 Build_OP (TOP_sb, store1, newbase, Gen_Literal_TN(1, 4), ops);
00482
00483 Build_OP(TOP_extrbu, store2, obj, Gen_Literal_TN(23, 4), Gen_Literal_TN(8, 4), ops);
00484 Build_OP (TOP_sb, store2, newbase, Gen_Literal_TN(2, 4), ops);
00485
00486 Build_OP(TOP_extrbu, store3, obj, Gen_Literal_TN(31, 4), Gen_Literal_TN(8, 4), ops);
00487 Build_OP (TOP_sb, store3, newbase, Gen_Literal_TN(3, 4), ops);
00488
00489 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
00490 return;
00491 case MTYPE_I2:
00492 case MTYPE_U2:
00493 Build_OP (TOP_sb, obj, base, disp, ops);
00494
00495 Expand_Add (newbase, base, disp, MTYPE_I4, ops);
00496 Build_OP(TOP_extrbu, store1, obj, Gen_Literal_TN(15, 4), Gen_Literal_TN(8, 4), ops);
00497 Build_OP (TOP_sb, store1, newbase, Gen_Literal_TN(1, 4), ops);
00498 return;
00499 default:
00500 FmtAssert (FALSE, ("Expand_Composed_Load: unexpected operand size\n"));
00501 }
00502 }
00503 }
00504 #else
00505 static void
00506 Expand_Composed_Store (TYPE_ID mtype, TN *obj, TN *base, TN *disp, VARIANT variant, OPS *ops)
00507 {
00508 if (MTYPE_is_float(mtype))
00509 {
00510 TN *tmp;
00511
00512 if (mtype == MTYPE_F4)
00513 {
00514 tmp = Build_TN_Of_Mtype(MTYPE_I4);
00515 Build_OP ( TOP_mfc1, tmp, obj, ops );
00516 Expand_Composed_Store (MTYPE_I4, tmp, base, disp, variant, ops);
00517 }
00518 else
00519 {
00520 tmp = Build_TN_Of_Mtype(MTYPE_I8);
00521 Build_OP ( TOP_dmfc1, tmp, obj, ops );
00522 Expand_Composed_Store (MTYPE_I8, tmp, base, disp, variant, ops);
00523 }
00524 return;
00525 }
00526
00527 TN *tmp;
00528 switch (mtype) {
00529 case MTYPE_I8:
00530 case MTYPE_U8:
00531 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_sdl : TOP_sdr,
00532 obj, base, disp, ops);
00533
00534 Adjust_Addr_TNs (Target_Byte_Sex == BIG_ENDIAN ? TOP_sdr : TOP_sdl,
00535 &base, &disp, 7, ops);
00536 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_sdr : TOP_sdl,
00537 obj, base, disp, ops);
00538 return;
00539 case MTYPE_I4:
00540 case MTYPE_U4:
00541 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_swl : TOP_swr,
00542 obj, base, disp, ops);
00543
00544 Adjust_Addr_TNs (Target_Byte_Sex == BIG_ENDIAN ? TOP_swl : TOP_swr,
00545 &base, &disp, 3, ops);
00546 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_swr : TOP_swl,
00547 obj, base, disp, ops);
00548 return;
00549 case MTYPE_I2:
00550 case MTYPE_U2:
00551 if (Target_Byte_Sex == BIG_ENDIAN) {
00552 tmp = Build_TN_Of_Mtype(mtype);
00553 Build_OP (TOP_srl, tmp, obj, Gen_Literal_TN(8, 4), ops);
00554 Build_OP (TOP_sb, tmp, base, disp, ops);
00555
00556 Adjust_Addr_TNs (TOP_lb, &base, &disp, 1, ops);
00557 Build_OP (TOP_sb, obj, base, disp, ops);
00558 } else {
00559 Build_OP (TOP_sb, obj, base, disp, ops);
00560
00561 Adjust_Addr_TNs (TOP_lb, &base, &disp, 1, ops);
00562 tmp = Build_TN_Of_Mtype(mtype);
00563 Build_OP (TOP_srl, tmp, obj, Gen_Literal_TN(8, 4), ops);
00564 Build_OP (TOP_sb, tmp, base, disp, ops);
00565 }
00566 return;
00567 default:
00568 FmtAssert (FALSE, ("Expand_Composed_Load: unexpected operand size\n"));
00569 }
00570 }
00571 #endif
00572
00573 void
00574 Expand_Misaligned_Store (TYPE_ID mtype, TN *obj_tn, TN *base_tn, TN *disp_tn, VARIANT variant, OPS *ops)
00575 {
00576 Expand_Composed_Store (mtype, obj_tn, base_tn, disp_tn, variant, ops);
00577 }
00578
00579
00580 BOOL Is_Stack_Used(void)
00581 {
00582 return FALSE;
00583 }
00584
00585 #ifdef TARG_SL
00586
00587
00588
00589
00590
00591
00592 TN_RELOCS
00593 Get_Internal_Buf_Reloc_Type( ST* st, INTRINSIC id) {
00594 TN_RELOCS reloc = TN_RELOC_NONE;
00595 Is_True((ST_in_vbuf(st) || ST_in_sbuf(st)), (" Passing a non-vbuf variable to Get_Vbuf_Reloc_Type"));
00596 if( id == INTRN_VBUF_OFFSET || id==INTRN_SBUF_OFFSET ) {
00597 if(ST_in_v1buf(st)) return TN_RELOC_GPREL_V1_15;
00598 else if(ST_in_v2buf(st)) return TN_RELOC_GPREL_V2_15;
00599 else if(ST_in_v4buf(st)) return TN_RELOC_GPREL_V4_15;
00600 else return TN_RELOC_GPREL_S;
00601 }
00602 }
00603 #endif
00604
00605
00606 #ifdef TARG_SL
00607 static void
00608 Exp_Ldst (
00609 OPCODE opcode,
00610 TN *tn,
00611 ST *sym,
00612 INT64 ofst,
00613 BOOL indirect_call,
00614 BOOL is_store,
00615 BOOL is_load,
00616 OPS *ops,
00617 VARIANT variant,
00618 BOOL is_internal_mem_ofst = FALSE)
00619 #else
00620 static void
00621 Exp_Ldst (
00622 OPCODE opcode,
00623 TN *tn,
00624 ST *sym,
00625 INT64 ofst,
00626 BOOL indirect_call,
00627 BOOL is_store,
00628 BOOL is_load,
00629 OPS *ops,
00630 VARIANT variant)
00631 #endif
00632 {
00633 ST *base_sym;
00634 INT64 base_ofst;
00635 TN *base_tn;
00636 TN *ofst_tn;
00637 TN *tmp_tn;
00638 BOOL is_lda = (!is_load && !is_store);
00639 OPS newops;
00640 OP *op;
00641 OPS_Init(&newops);
00642
00643 if (Trace_Exp2) {
00644 fprintf(TFile, "exp_ldst %s: ", OPCODE_name(opcode));
00645 if (tn) Print_TN(tn,FALSE);
00646 if (is_store) fprintf(TFile, " -> ");
00647 else fprintf(TFile, " <- ");
00648 if (ST_class(sym) != CLASS_CONST)
00649 fprintf(TFile, "%lld (%s)\n", ofst, ST_name(sym));
00650 else
00651 fprintf(TFile, "%lld ()\n", ofst);
00652 }
00653
00654 Allocate_Object(sym);
00655
00656 Base_Symbol_And_Offset_For_Addressing (sym, ofst, &base_sym, &base_ofst);
00657
00658 if (base_sym == SP_Sym || base_sym == FP_Sym) {
00659 base_tn = (base_sym == SP_Sym) ? SP_TN : FP_TN;
00660 if (sym == base_sym) {
00661
00662
00663 if (ISA_LC_Value_In_Class(base_ofst, LC_simm16))
00664 ofst_tn = Gen_Literal_TN (base_ofst, 4);
00665 else {
00666 tmp_tn = Build_TN_Of_Mtype(Pointer_Mtype);
00667 Build_OP(TOP_lui, tmp_tn,
00668 Gen_Literal_TN(base_ofst >> 16, 4), &newops);
00669 Build_OP(Use_32_Bit_Pointers ? TOP_addu : TOP_daddu, tmp_tn,
00670 tmp_tn, base_tn, &newops);
00671 base_tn = tmp_tn;
00672 ofst_tn = Gen_Literal_TN (base_ofst & 0xffff, 4);
00673 }
00674 }
00675 else {
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 if (ISA_LC_Value_In_Class(base_ofst, LC_simm16))
00686 ofst_tn = Gen_Symbol_TN (sym, ofst, 0);
00687 else {
00688 tmp_tn = Build_TN_Of_Mtype(Pointer_Mtype);
00689 Build_OP(TOP_lui, tmp_tn,
00690 Gen_Symbol_TN(sym, ofst, TN_RELOC_HIGH16), &newops);
00691 Build_OP(Use_32_Bit_Pointers ? TOP_addu : TOP_daddu, tmp_tn,
00692 tmp_tn, base_tn, &newops);
00693 base_tn = tmp_tn;
00694 ofst_tn = Gen_Symbol_TN(sym, ofst, TN_RELOC_LOW16);
00695 }
00696 }
00697 }
00698 else if ((ST_class(base_sym) == CLASS_BLOCK || ST_class(base_sym)==CLASS_VAR)
00699 && ST_gprel(base_sym))
00700 {
00701
00702 PU_References_GP = TRUE;
00703
00704 if (ISA_LC_Value_In_Class(base_ofst, LC_simm16)) {
00705 base_tn = GP_TN;
00706
00707 #ifdef TARG_SL
00708 if (is_internal_mem_ofst && ST_in_vbuf(sym)) {
00709 base_tn = Zero_TN;
00710 ofst_tn = Gen_Symbol_TN(sym, ofst, TN_RELOC_GPREL_SL2_V15);
00711 Set_TN_is_v1buf_addr(tn);
00712 }
00713 else if ( is_internal_mem_ofst && ST_in_sbuf(sym) ) {
00714 base_tn = Zero_TN;
00715 ofst_tn = Gen_Symbol_TN(sym, ofst, TN_RELOC_GPREL_S);
00716 }
00717 else
00718 #endif
00719 ofst_tn = Gen_Symbol_TN (sym, ofst, TN_RELOC_GPREL16);
00720 }
00721 else {
00722 FmtAssert(FALSE, ("gp-relative offset doesn't fit in 16 bits"));
00723 }
00724 }
00725 else if (! Gen_PIC_Shared) {
00726 base_tn = Build_TN_Of_Mtype(Pointer_Mtype);
00727 Build_OP(TOP_lui, base_tn,
00728 Gen_Symbol_TN(base_sym, base_ofst, TN_RELOC_HIGH16), &newops);
00729 ofst_tn = Gen_Symbol_TN(base_sym, base_ofst, TN_RELOC_LOW16);
00730 }
00731 else if (Guaranteed_Small_GOT) {
00732 TN *tmp2;
00733 if (! ST_is_export_local(base_sym) &&
00734 ! ISA_LC_Value_In_Class(base_ofst, LC_simm16)) {
00735 tmp2 = Build_TN_Of_Mtype (Pointer_Mtype);
00736 Expand_Load (
00737
00738 OPCODE_make_signed_op(OPR_LDID, Pointer_Mtype, Pointer_Mtype, FALSE),
00739 tmp2, GP_TN, Gen_Symbol_TN(base_sym, base_ofst, TN_RELOC_GOT_PAGE),
00740 &newops);
00741
00742 Set_OP_no_alias(OPS_last(&newops));
00743 base_tn = tmp2;
00744
00745 ofst_tn = Gen_Symbol_TN(base_sym, base_ofst, TN_RELOC_GOT_OFST);
00746 }
00747 else {
00748 if (is_lda && OFFSET_LO(base_ofst) == 0) {
00749
00750 tmp2 = tn;
00751 is_lda = FALSE;
00752 }
00753 else tmp2 = Build_TN_Of_Mtype (Pointer_Mtype);
00754 Expand_Load (
00755
00756 OPCODE_make_signed_op(OPR_LDID, Pointer_Mtype, Pointer_Mtype, FALSE),
00757 tmp2, GP_TN,
00758 Gen_Symbol_TN(base_sym, OFFSET_HI(base_ofst), TN_RELOC_GOT_DISP),
00759 &newops);
00760
00761 Set_OP_no_alias(OPS_last(&newops));
00762 base_tn = tmp2;
00763
00764 ofst_tn = Gen_Literal_TN(OFFSET_LO(base_ofst), 4);
00765 }
00766 }
00767 else {
00768 FmtAssert(FALSE, ("NYI: Exp_Ldst"));
00769 }
00770
00771 if (is_store) {
00772 if (variant == 0)
00773 Expand_Store (OPCODE_desc(opcode), tn, base_tn, ofst_tn, &newops);
00774 else
00775 Expand_Misaligned_Store (OPCODE_desc(opcode), tn,
00776 base_tn, ofst_tn, variant, &newops);
00777 }
00778 else if (is_load) {
00779 if (variant == 0)
00780 Expand_Load (opcode, tn, base_tn, ofst_tn, &newops);
00781 else
00782 Expand_Misaligned_Load (opcode, tn,
00783 base_tn, ofst_tn, variant, &newops);
00784 }
00785 else if (is_lda) {
00786 if (TN_is_symbol(ofst_tn))
00787 Build_OP(Use_32_Bit_Pointers?TOP_addiu:TOP_daddiu,
00788 tn, base_tn, ofst_tn, &newops);
00789 else Expand_Add (tn, ofst_tn, base_tn, OPCODE_rtype(opcode), &newops);
00790 }
00791
00792 FOR_ALL_OPS_OPs (&newops, op) {
00793 if (is_load && ST_is_constant(sym) && OP_load(op)) {
00794
00795
00796
00797 Set_OP_no_alias(op);
00798 }
00799 if (Trace_Exp2) {
00800 fprintf(TFile, "exp_ldst into "); Print_OP (op);
00801 }
00802 }
00803
00804 OPS_Append_Ops(ops, &newops);
00805 }
00806
00807 #ifdef TARG_SL
00808 void Exp_Lda (
00809 TYPE_ID mtype,
00810 TN *tgt_tn,
00811 ST *sym,
00812 INT64 ofst,
00813 OPERATOR call_opr,
00814 OPS *ops,
00815 BOOL is_internal_mem_ofst)
00816 #else
00817 void Exp_Lda (
00818 TYPE_ID mtype,
00819 TN *tgt_tn,
00820 ST *sym,
00821 INT64 ofst,
00822 OPERATOR call_opr,
00823 OPS *ops)
00824 #endif
00825 {
00826 OPCODE opcode = OPCODE_make_op(OPR_LDA, mtype, MTYPE_V);
00827 #ifdef TARG_SL
00828 Exp_Ldst (opcode, tgt_tn, sym, ofst,
00829 (call_opr == OPR_ICALL),
00830 FALSE, FALSE, ops, 0, is_internal_mem_ofst);
00831 #else
00832 Exp_Ldst (opcode, tgt_tn, sym, ofst,
00833 (call_opr == OPR_ICALL),
00834 FALSE, FALSE, ops, 0);
00835 #endif
00836 }
00837
00838 void
00839 Exp_Load (
00840 TYPE_ID rtype,
00841 TYPE_ID desc,
00842 TN *tgt_tn,
00843 ST *sym,
00844 INT64 ofst,
00845 OPS *ops,
00846 VARIANT variant)
00847 {
00848 OPCODE opcode = OPCODE_make_op (OPR_LDID, rtype, desc);
00849 Exp_Ldst (opcode, tgt_tn, sym, ofst, FALSE, FALSE, TRUE, ops, variant);
00850 }
00851
00852 void
00853 Exp_Store (
00854 TYPE_ID mtype,
00855 TN *src_tn,
00856 ST *sym,
00857 INT64 ofst,
00858 OPS *ops,
00859 VARIANT variant)
00860 {
00861 OPCODE opcode = OPCODE_make_op(OPR_STID, MTYPE_V, mtype);
00862 Exp_Ldst (opcode, src_tn, sym, ofst, FALSE, TRUE, FALSE, ops, variant);
00863 }
00864
00865 static ISA_ENUM_CLASS_VALUE
00866 Pick_Prefetch_Hint (VARIANT variant)
00867 {
00868 UINT32 pf_flags = V_pf_flags(variant);
00869 if (PF_GET_READ(pf_flags)) {
00870 if (PF_GET_STRIDE_1L(pf_flags))
00871 return ECV_pfhint_L1_load;
00872 else return ECV_pfhint_L2_load;
00873 }
00874 else {
00875 if (PF_GET_STRIDE_1L(pf_flags))
00876 return ECV_pfhint_L1_store;
00877 else return ECV_pfhint_L2_store;
00878 }
00879 }
00880
00881 void Exp_Prefetch (TOP opc, TN* src1, TN* src2, VARIANT variant, OPS* ops)
00882 {
00883 ISA_ENUM_CLASS_VALUE pfhint;
00884 FmtAssert(opc == TOP_UNDEFINED,
00885 ("Prefetch opcode should be selected in Exp_Prefetch"));
00886 pfhint = Pick_Prefetch_Hint(variant);
00887 Build_OP(TOP_pref, Gen_Enum_TN(pfhint), src1, src2, ops);
00888 }
00889
00890
00891
00892
00893 #if defined(TARG_SL)
00894 void
00895 Exp_Extract_Bits (TYPE_ID rtype, TYPE_ID desc, UINT bit_offset, UINT bit_size,
00896 TN *tgt_tn, TN *src_tn, OPS *ops)
00897 {
00898 UINT adjust_offset = (bit_offset + bit_size) - 1;
00899 if(MTYPE_signed(rtype)) {
00900 Build_OP(TOP_extrbs, tgt_tn, src_tn, Gen_Literal_TN(adjust_offset, 4), Gen_Literal_TN(bit_size, 4), ops);
00901 }
00902 else {
00903 Build_OP(TOP_extrbu, tgt_tn, src_tn, Gen_Literal_TN(adjust_offset, 4), Gen_Literal_TN(bit_size, 4), ops);
00904 }
00905 }
00906 #else
00907 void
00908 Exp_Extract_Bits (TYPE_ID rtype, TYPE_ID desc, UINT bit_offset, UINT bit_size,
00909 TN *tgt_tn, TN *src_tn, OPS *ops)
00910 {
00911 TN *tmp1_tn = Build_TN_Like (tgt_tn);
00912 UINT pos = (Target_Byte_Sex == BIG_ENDIAN || CG_emit_non_gas_syntax)
00913 ? MTYPE_bit_size(desc)-bit_offset-bit_size : bit_offset;
00914 if (pos == 0 && bit_size <= 16 && ! MTYPE_signed(rtype)) {
00915 Build_OP(TOP_andi, tgt_tn, src_tn,
00916 Gen_Literal_TN((1 << bit_size)-1, 4), ops);
00917 return;
00918 }
00919
00920 TOP left_shift_op = TOP_sll;
00921 INT left_shift_amt = MTYPE_bit_size(rtype) - pos - bit_size;
00922 if (MTYPE_is_size_double(rtype)) {
00923 left_shift_op = TOP_dsll;
00924 if (left_shift_amt > 31) {
00925 left_shift_op = TOP_dsll32;
00926 left_shift_amt -= 32;
00927 }
00928 }
00929 Build_OP(left_shift_op, tmp1_tn, src_tn, Gen_Literal_TN(left_shift_amt, 4),
00930 ops);
00931 TOP right_shift_op = TOP_sra;
00932 INT right_shift_amt = MTYPE_bit_size(rtype) - bit_size;
00933 if (MTYPE_is_size_double(rtype)) {
00934 right_shift_op = TOP_dsra;
00935 if (right_shift_amt > 31) {
00936 right_shift_op = TOP_dsra32;
00937 right_shift_amt -= 32;
00938 }
00939 }
00940 if (! MTYPE_signed(rtype)) {
00941 if (right_shift_op == TOP_sra)
00942 right_shift_op = TOP_srl;
00943 else if (right_shift_op == TOP_dsra)
00944 right_shift_op = TOP_dsrl;
00945 else right_shift_op = TOP_dsrl32;
00946 }
00947 Build_OP(right_shift_op, tgt_tn, tmp1_tn, Gen_Literal_TN(right_shift_amt, 4),
00948 ops);
00949 }
00950 #endif
00951
00952
00953
00954
00955
00956 #if defined(TARG_SL)
00957 void
00958 Exp_Deposit_Bits (TYPE_ID rtype, TYPE_ID desc, UINT bit_offset, UINT bit_size,
00959 TN *tgt_tn, TN *src1_tn, TN *src2_tn, OPS *ops)
00960 {
00961 FmtAssert(bit_size != 0, ("size of bit field cannot be 0"));
00962 UINT adjust_offset = (bit_offset + bit_size) - 1;
00963 if(tgt_tn!=src1_tn) {
00964
00965 Expand_Add (tgt_tn, src1_tn, Zero_TN, MTYPE_I4, ops);
00966 }
00967 Build_OP(TOP_depb, tgt_tn, tgt_tn, src2_tn, Gen_Literal_TN(adjust_offset, 4), Gen_Literal_TN(bit_size, 4), ops);
00968
00969 }
00970 #else
00971 void
00972 Exp_Deposit_Bits (TYPE_ID rtype, TYPE_ID desc, UINT bit_offset, UINT bit_size,
00973 TN *tgt_tn, TN *src1_tn, TN *src2_tn, OPS *ops)
00974 {
00975 FmtAssert(bit_size != 0, ("size of bit field cannot be 0"));
00976
00977 UINT targ_bit_offset = bit_offset;
00978 if (Target_Byte_Sex == BIG_ENDIAN) {
00979 targ_bit_offset = MTYPE_bit_size(desc) - bit_offset - bit_size;
00980 }
00981 TN *tmp1_tn = Build_TN_Like (src1_tn);
00982 TOP shift_op = TOP_srl;
00983 INT shift_amt = targ_bit_offset;
00984 if (MTYPE_is_size_double(rtype)) {
00985 shift_op = TOP_dsrl;
00986 if (shift_amt > 31) {
00987 shift_op = TOP_dsrl32;
00988 shift_amt -= 32;
00989 }
00990 }
00991 Build_OP(shift_op, tmp1_tn, src1_tn, Gen_Literal_TN(shift_amt,4), ops);
00992 Build_OP(TOP_xor, tmp1_tn, tmp1_tn, src2_tn, ops);
00993 shift_op = TOP_sll;
00994 shift_amt = MTYPE_bit_size(rtype) - bit_size;
00995 if (MTYPE_is_size_double(rtype)) {
00996 shift_op = TOP_dsll;
00997 if (shift_amt > 31) {
00998 shift_op = TOP_dsll32;
00999 shift_amt -= 32;
01000 }
01001 }
01002 Build_OP(shift_op, tmp1_tn, tmp1_tn, Gen_Literal_TN(shift_amt, 4), ops);
01003 shift_op = TOP_srl;
01004 shift_amt = MTYPE_bit_size(rtype) - bit_size - targ_bit_offset;
01005 if (MTYPE_is_size_double(rtype)) {
01006 shift_op = TOP_dsrl;
01007 if (shift_amt > 31) {
01008 shift_op = TOP_dsrl32;
01009 shift_amt -= 32;
01010 }
01011 }
01012 Build_OP(shift_op, tmp1_tn, tmp1_tn, Gen_Literal_TN(shift_amt, 4), ops);
01013 Build_OP(TOP_xor, tgt_tn, src1_tn, tmp1_tn, ops);
01014 }
01015 #endif
01016
01017 void
01018 Expand_Lda_Label (TN *dest, TN *lab, OPS *ops)
01019 {
01020 Set_TN_is_reloc_got_disp(lab);
01021 if (Use_32_Bit_Pointers)
01022 Build_OP(TOP_lw, dest, GP_TN, lab, ops);
01023 else
01024 Build_OP(TOP_ld, dest, GP_TN, lab, ops);
01025 }