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 extern TN *Get_64Bit_High_TN(TN *low, TYPE_ID type, OPS * ops);
00067 extern TN *Get_TN_Pair(TN *key);
00068 extern void Add_TN_Pair(TN *key, TN *pair);
00069
00070 #define OFFSET_HI(offset) ((((offset) + 0x8000) >> 16) << 16)
00071 #define OFFSET_LO(offset) ((((offset) + 0x8000) & 0xffff) - 0x8000)
00072
00073 void
00074 Expand_Lda (TN *dest, TN *src, OPS *ops)
00075 {
00076 FmtAssert(FALSE, ("NYI: Expand_Lda"));
00077 }
00078
00079 static TOP
00080 Pick_Load_Instruction (TYPE_ID rtype, TYPE_ID desc)
00081 {
00082 switch (desc) {
00083 case MTYPE_I1: return TOP_lb;
00084 case MTYPE_U1: return TOP_lbu;
00085 case MTYPE_I2: return TOP_lh;
00086 case MTYPE_U2: return TOP_lhu;
00087 case MTYPE_I4:
00088 case MTYPE_U4:
00089 case MTYPE_I8:
00090 case MTYPE_U8:
00091 case MTYPE_F4:
00092 case MTYPE_F8: return TOP_lw;
00093
00094 case MTYPE_V:
00095 if (rtype != MTYPE_V)
00096
00097 return Pick_Load_Instruction(rtype,rtype);
00098
00099 default:
00100 FmtAssert(FALSE, ("NYI: Pick_Load_Instruction mtype"));
00101 return TOP_UNDEFINED;
00102 }
00103 }
00104
00105 #if defined(TARG_SL)
00106
00107 #define max_ofst 31
00108
00109 BOOL
00110 Expand_V1buf_Ldst(TOP top, TN* value, TN* base, TN* ofst, BOOL is_load, OPS* ops)
00111 {
00112
00113
00114
00115 if(is_load) {
00116 if(TN_is_symbol(ofst)) {
00117 INT64 ofst_val;
00118 ST* st = TN_var(ofst);
00119 ofst_val = TN_value(ofst);
00120 if(ST_in_v1buf(st)) {
00121 ofst = Gen_Symbol_TN(st, ofst_val,
00122 TN_RELOC_GPREL_SL2_V15);
00123 if(top == TOP_lbu)
00124 top = TOP_c2_ldi_v2g_b_u;
00125 else if(top == TOP_lb)
00126 top = TOP_c2_ldi_v2g_b;
00127 else
00128 Fail_FmtAssertion("no lbu/lb found");
00129 Build_OP(top, value, ofst, ops);
00130 return TRUE;
00131 }
00132 }
00133 else if(TN_is_v1buf_addr(base)) {
00134 if(top == TOP_lbu)
00135 top = TOP_c2_ld_v2g_b_u;
00136 else if(top == TOP_lb)
00137 top = TOP_c2_ld_v2g_b;
00138 else
00139 Fail_FmtAssertion("no lbu/lb found");
00140
00141 if(TN_value(ofst) > max_ofst) {
00142 Build_OP(TOP_addiu, base, base, ofst, ops);
00143 ofst = Gen_Literal_TN(0, 4);
00144 }
00145 Build_OP(top, value, base, ofst, ops);
00146 return TRUE;
00147 }
00148 }
00149 else {
00150
00151
00152 if(TN_is_symbol(ofst)) {
00153 INT64 ofst_val;
00154 ST* st = TN_var(ofst);
00155 ofst_val = TN_value(ofst);
00156 if(ST_in_v1buf(st)) {
00157 ofst = Gen_Symbol_TN(st, ofst_val,
00158 TN_RELOC_GPREL_SL2_V15);
00159 Build_OP(TOP_c2_sti_g2v_b, value, ofst, ops);
00160 return TRUE;
00161 }
00162 }
00163 else if (TN_is_v1buf_addr(base)) {
00164 if(TN_value(ofst) > max_ofst) {
00165 Build_OP(TOP_addiu, base, base, ofst, ops);
00166 ofst = Gen_Literal_TN(0, 4);
00167 }
00168 Build_OP(TOP_c2_st_g2v_b, value, base, ofst, ops);
00169 return TRUE;
00170 }
00171 }
00172 return FALSE;
00173 }
00174 #endif
00175
00176 static TN *
00177 Get_64Bit_High_Addr(TN *base, TN ** ofst, TN ** ofst_h, OPS * ops)
00178 {
00179 if (TN_is_constant(*ofst) && ISA_LC_Value_In_Class(TN_value(*ofst) + 4, LC_simm16)) {
00180 *ofst_h = TN_is_symbol(*ofst) ?
00181 Gen_Symbol_TN(TN_var(*ofst), TN_offset(*ofst)+4, TN_relocs(*ofst)) :
00182 Gen_Literal_TN(TN_value(*ofst)+4, TN_size(*ofst));
00183
00184 return base;
00185 } else {
00186 TN *new_base = Build_TN_Of_Mtype(MTYPE_U4);
00187 Expand_Add(new_base, base, *ofst, MTYPE_U4, ops);
00188 *ofst = Gen_Literal_TN(0, 4);
00189 *ofst_h = Gen_Literal_TN(4, 4);
00190
00191 return new_base;
00192 }
00193 }
00194
00195 static void
00196 Expand_64Bit_Load(OPCODE opcode, TN *result, TN *base, TN *ofst, OPS* ops)
00197 {
00198 TYPE_ID desc = OPCODE_desc(opcode);
00199 TYPE_ID rtype = OPCODE_rtype(opcode);
00200
00201 FmtAssert(MTYPE_byte_size(rtype) == 8, ("Expand_64Bit_Load: NYI"));
00202
00203 TN *result_h = Get_TN_Pair(result);
00204
00205 if (MTYPE_is_longlong(rtype)) {
00206 TYPE_ID new_mtype = (rtype == MTYPE_I8 ? MTYPE_I4 : MTYPE_U4);
00207 TYPE_ID new_desc = MTYPE_is_longlong(desc) ? new_mtype : desc;
00208 TOP new_top = Pick_Load_Instruction(new_mtype, new_desc);
00209
00210 if (MTYPE_is_longlong(desc)){
00211 TN *ofst_h = NULL;
00212 TN *new_base = Get_64Bit_High_Addr(base, &ofst, &ofst_h, ops);
00213 Build_OP(new_top, result, new_base, ofst, ops);
00214
00215
00216
00217
00218 if (result_h != NULL) {
00219 Build_OP(new_top, result_h, new_base, ofst_h, ops);
00220 }
00221 } else {
00222 Build_OP(new_top, result, base, ofst, ops);
00223
00224 if (result_h != NULL) {
00225 if (MTYPE_signed(desc)) {
00226 Build_OP(TOP_sra, result_h, result, Gen_Literal_TN(31, 4), ops);
00227 } else {
00228 Build_OP(TOP_or, result_h, Zero_TN, Zero_TN, ops);
00229 }
00230 }
00231 }
00232 }else if (MTYPE_is_double(desc)) {
00233 TN *ofst_h = NULL;
00234 TN *new_base = Get_64Bit_High_Addr(base, &ofst, &ofst_h, ops);
00235
00236 Build_OP(TOP_lw, result, new_base, ofst, ops);
00237
00238
00239
00240
00241 if (result_h != NULL) {
00242 Build_OP(TOP_lw, result_h, new_base, ofst_h, ops);
00243 }
00244 }
00245 }
00246
00247 void
00248 Expand_Load (OPCODE opcode, TN *result, TN *base, TN *ofst, OPS *ops)
00249 {
00250 TYPE_ID mtype = OPCODE_desc(opcode);
00251 TOP top = Pick_Load_Instruction (OPCODE_rtype(opcode), mtype);
00252 Is_True (TN_is_constant(ofst), ("Expand_Load: Illegal offset TN"));
00253
00254
00255
00256 if (TN_is_rematerializable(base) &&
00257 (!ISA_LC_Value_In_Class(TN_value(ofst), LC_simm16))) {
00258 WN *home = TN_home(base);
00259 if (WN_operator(home) == OPR_INTCONST) {
00260 INT64 val = WN_const_val(home);
00261 BOOL is_double = TN_size(base) == 8;
00262 TN *tmp_base = Gen_Literal_TN (val + TN_value(ofst), TN_size(base));
00263 tmp_base = Expand_Immediate_Into_Register(tmp_base, is_double, ops);
00264 Build_OP (top, result, tmp_base, Gen_Literal_TN (0, 4), ops);
00265 if (MTYPE_is_longlong(OPCODE_rtype(opcode)))
00266 Build_OP (top, Get_TN_Pair(result), tmp_base, Gen_Literal_TN (4, 4), ops);
00267 return;
00268 }
00269 }
00270 #if defined(TARG_SL)
00271 if(CG_sl2 && CG_SL2_enable_v1buf_expansion &&
00272 Expand_V1buf_Ldst(top, result, base, ofst, TRUE, ops)) return;
00273 #endif
00274 if (MTYPE_byte_size(OPCODE_rtype(opcode)) == 8) {
00275 Expand_64Bit_Load(opcode, result, base, ofst, ops);
00276 } else {
00277 Build_OP (top, result, base, ofst, ops);
00278 }
00279 }
00280
00281 static TOP
00282 Pick_Store_Instruction (TYPE_ID mtype)
00283 {
00284 switch (mtype) {
00285 case MTYPE_I1: case MTYPE_U1: return TOP_sb;
00286 case MTYPE_I2: case MTYPE_U2: return TOP_sh;
00287 case MTYPE_I4: case MTYPE_U4: return TOP_sw;
00288 case MTYPE_I8: case MTYPE_U8: return TOP_sw;
00289 case MTYPE_F4: return TOP_sw;
00290 case MTYPE_F8: return TOP_sw;
00291 default:
00292 FmtAssert(FALSE, ("NYI: Pick_Store_Instruction mtype"));
00293 return TOP_UNDEFINED;
00294 }
00295 }
00296
00297 static void
00298 Expand_64Bit_Store(TYPE_ID mtype, TN *src, TN *base, TN *ofst, OPS *ops)
00299 {
00300 TN *src_h = Get_TN_Pair(src);
00301 TN *ofst_h = NULL;
00302 TN *new_base = Get_64Bit_High_Addr(base, &ofst, &ofst_h, ops);
00303
00304 if (MTYPE_is_longlong(mtype)) {
00305 TYPE_ID new_mtype = (mtype == MTYPE_I8 ? MTYPE_I4 : MTYPE_U4);
00306 TOP new_top = Pick_Store_Instruction(new_mtype);
00307
00308 if (src_h == NULL){
00309 src_h = Get_64Bit_High_TN(src, mtype, ops);
00310 }
00311
00312 Build_OP(new_top, src, new_base, ofst, ops);
00313 Build_OP(new_top, src_h, new_base, ofst_h, ops);
00314 } else if (MTYPE_is_double(mtype)) {
00315
00316 Build_OP(TOP_sw, src, new_base, ofst, ops);
00317
00318
00319
00320
00321 if (src_h != NULL) {
00322 Build_OP(TOP_sw, src_h, new_base, ofst_h, ops);
00323 }
00324 }
00325 }
00326
00327 void
00328 Expand_Store (TYPE_ID mtype, TN *src, TN *base, TN *ofst, OPS *ops)
00329 {
00330 TOP top = Pick_Store_Instruction (mtype);
00331 Is_True (TN_is_constant(ofst), ("Expand_Store: Illegal offset TN"));
00332
00333 #if defined(TARG_SL)
00334 if(CG_sl2 && CG_SL2_enable_v1buf_expansion &&
00335 Expand_V1buf_Ldst(top, src, base, ofst, FALSE, ops)) return;
00336 #endif
00337
00338 if(MTYPE_byte_size(mtype) == 8) {
00339 Expand_64Bit_Store(mtype, src, base, ofst, ops);
00340 return;
00341 }
00342 if (!TN_has_value(ofst) || ISA_LC_Value_In_Class(TN_value(ofst), LC_simm16))
00343 Build_OP (top, src, base, ofst, ops);
00344 else {
00345 TN *tmp_tn = Build_TN_Of_Mtype(Pointer_Mtype);
00346 INT32 tmp = TN_value(ofst) >> 16;
00347 if (tmp < 0) {
00348
00349 if (Use_32_Bit_Pointers)
00350 tmp &= 0xffff;
00351 }
00352 Build_OP(TOP_lui, tmp_tn, Gen_Literal_TN(tmp, 4), ops);
00353 Build_OP(Use_32_Bit_Pointers ? TOP_addu : TOP_daddu, tmp_tn,
00354 tmp_tn, base, ops);
00355 Build_OP(top, src, tmp_tn, Gen_Literal_TN(TN_value(ofst)&0xffff, 4), ops);
00356 }
00357 }
00358
00359 static OPCODE
00360 OPCODE_make_signed_op(OPERATOR op, TYPE_ID rtype, TYPE_ID desc, BOOL is_signed)
00361 {
00362 if (MTYPE_is_signed(rtype) != is_signed)
00363 rtype = MTYPE_complement(rtype);
00364 if (MTYPE_is_signed(desc) != is_signed)
00365 desc = MTYPE_complement(desc);
00366
00367 return OPCODE_make_op(op, rtype, desc);
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383 static void
00384 Adjust_Addr_TNs (
00385 TOP opcode,
00386 TN **base_tn,
00387 TN **disp_tn,
00388 INT16 disp,
00389 OPS *ops)
00390 {
00391
00392 if ( Potential_Immediate_TN_Expr (opcode, *disp_tn, disp) )
00393 {
00394 if ( TN_has_value(*disp_tn) ) {
00395 *disp_tn = Gen_Literal_TN ( TN_value(*disp_tn) + disp, 4 );
00396 } else {
00397 *disp_tn = Gen_Symbol_TN ( TN_var(*disp_tn),
00398 TN_offset(*disp_tn) + disp, 0);
00399 }
00400 } else {
00401 TN *tmp = Build_TN_Of_Mtype (Pointer_Mtype);
00402
00403
00404 Expand_Add (tmp, *disp_tn, *base_tn, Pointer_Mtype, ops);
00405 *base_tn = tmp;
00406 *disp_tn = Gen_Literal_TN (disp, 4);
00407 }
00408 }
00409
00410 #ifdef TARG_SL
00411 static void
00412 Expand_Composed_Load ( OPCODE op, TN *result, TN *base, TN *disp, VARIANT variant, OPS *ops)
00413 {
00414 TYPE_ID rtype= OPCODE_rtype(op);
00415 TYPE_ID desc = OPCODE_desc(op);
00416 DevWarn ("Expand_Composed_Load: Unaligned load found");
00417 if (MTYPE_is_float(rtype)) {
00418 DevWarn ("Float type in Expand_Composed_Load");
00419 if (rtype == MTYPE_F4) {
00420 Expand_Composed_Load ( OPC_I4I4LDID, result, base, disp, variant, ops);
00421 } else {
00422 Expand_Composed_Load ( OPC_I8I8LDID, result, base, disp, variant, ops);
00423 }
00424 return;
00425 }
00426 else {
00427 TN *load1 = Build_TN_Of_Mtype(MTYPE_I4);
00428 TN *load2 = Build_TN_Of_Mtype(MTYPE_I4);
00429 TN *load3 = Build_TN_Of_Mtype(MTYPE_I4);
00430 TN *newbase = Build_TN_Of_Mtype(MTYPE_I4);
00431 switch (desc) {
00432 case MTYPE_I8:
00433 case MTYPE_U8:
00434 Expand_Add(newbase, base, disp, MTYPE_I4, ops);
00435
00436 Build_OP(TOP_lbu, result, base, disp, ops);
00437
00438 Build_OP(TOP_lbu, load1, newbase, Gen_Literal_TN(1, 4), ops);
00439 Build_OP(TOP_depb, result, result, load1, Gen_Literal_TN(15, 4), Gen_Literal_TN(8, 4), ops);
00440
00441 Build_OP(TOP_lbu, load2, newbase, Gen_Literal_TN(2, 4), ops);
00442 Build_OP(TOP_depb, result, result, load2, Gen_Literal_TN(23, 4), Gen_Literal_TN(8, 4), ops);
00443
00444 Build_OP(TOP_lbu, load3, newbase, Gen_Literal_TN(3, 4), ops);
00445 Build_OP(TOP_depb, result, result, load3, Gen_Literal_TN(31, 4), Gen_Literal_TN(8, 4), ops);
00446
00447 result = Get_TN_Pair(result);
00448 FmtAssert(result != NULL, ("result tn in Expand_Composed_Load not setup\n"));
00449
00450 Build_OP(TOP_lbu, result, newbase, Gen_Literal_TN(4, 4), ops);
00451
00452 Build_OP(TOP_lbu, load1, newbase, Gen_Literal_TN(5, 4), ops);
00453 Build_OP(TOP_depb, result, result, load1, Gen_Literal_TN(15, 4), Gen_Literal_TN(8, 4), ops);
00454
00455 Build_OP(TOP_lbu, load2, newbase, Gen_Literal_TN(6, 4), ops);
00456 Build_OP(TOP_depb, result, result, load2, Gen_Literal_TN(23, 4), Gen_Literal_TN(8, 4), ops);
00457
00458 Build_OP(TOP_lbu, load3, newbase, Gen_Literal_TN(7, 4), ops);
00459 Build_OP(TOP_depb, result, result, load3, Gen_Literal_TN(31, 4), Gen_Literal_TN(8, 4), ops);
00460 return;
00461 case MTYPE_I4:
00462 case MTYPE_U4:
00463 Build_OP (TOP_lbu, result, base, disp, ops);
00464
00465 Expand_Add (newbase, base, disp, MTYPE_I4, ops);
00466 Build_OP (TOP_lbu, load1, newbase, Gen_Literal_TN(1, 4), ops);
00467 Build_OP(TOP_depb, result, result, load1, Gen_Literal_TN(15, 4), Gen_Literal_TN(8, 4), ops);
00468
00469 Build_OP (TOP_lbu, load2, newbase, Gen_Literal_TN(2, 4), ops);
00470 Build_OP(TOP_depb, result, result, load2, Gen_Literal_TN(23, 4), Gen_Literal_TN(8, 4), ops);
00471
00472 Build_OP (TOP_lbu, load3, newbase, Gen_Literal_TN(3, 4), ops);
00473 Build_OP(TOP_depb, result, result, load3, Gen_Literal_TN(31, 4), Gen_Literal_TN(8, 4), ops);
00474
00475
00476 return;
00477 case MTYPE_I2:
00478 case MTYPE_U2:
00479 Build_OP (TOP_lbu, result, base, disp, ops);
00480
00481 Expand_Add (newbase, base, disp, MTYPE_I4, ops);
00482 Build_OP (TOP_lbu, load1, newbase, Gen_Literal_TN(1, 4), ops);
00483 Build_OP(TOP_depb, result, result, load1, Gen_Literal_TN(15, 4), Gen_Literal_TN(8, 4), ops);
00484 return;
00485 default:
00486 FmtAssert (FALSE, ("Expand_Composed_Load: unexpected operand size\n"));
00487 }
00488 }
00489 }
00490 #else
00491 static void
00492 Expand_Composed_Load ( OPCODE op, TN *result, TN *base, TN *disp, VARIANT variant, OPS *ops)
00493 {
00494 TYPE_ID rtype= OPCODE_rtype(op);
00495 TYPE_ID desc = OPCODE_desc(op);
00496 TN *tmp;
00497
00498 if (MTYPE_is_float(rtype)) {
00499 TN *load;
00500
00501 if (rtype == MTYPE_F4) {
00502 load = Build_TN_Of_Mtype(MTYPE_I4);
00503 Expand_Composed_Load ( OPC_I4I4LDID, load, base, disp, variant, ops);
00504
00505 Build_OP ( TOP_mtc1, result, load, ops );
00506 } else {
00507 load = Build_TN_Of_Mtype(MTYPE_I8);
00508 Expand_Composed_Load ( OPC_I8I8LDID, load, base, disp, variant, ops);
00509 Build_OP ( TOP_dmtc1, result, load, ops );
00510 }
00511 Reset_TN_is_fpu_int(result);
00512 return;
00513 }
00514
00515 switch (desc) {
00516 case MTYPE_I8:
00517 case MTYPE_U8:
00518 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_ldl : TOP_ldr,
00519 result, base, disp, ops);
00520
00521 Adjust_Addr_TNs (Target_Byte_Sex == BIG_ENDIAN ? TOP_ldr : TOP_ldl,
00522 &base, &disp, 7, ops);
00523 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_ldr : TOP_ldl,
00524 result, base, disp, ops);
00525 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
00526 return;
00527 case MTYPE_I4:
00528 case MTYPE_U4:
00529 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_lwl : TOP_lwr,
00530 result, base, disp, ops);
00531
00532 Adjust_Addr_TNs (Target_Byte_Sex == BIG_ENDIAN ? TOP_lwr : TOP_lwl,
00533 &base, &disp, 3, ops);
00534 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_lwr : TOP_lwl,
00535 result, base, disp, ops);
00536 Set_OP_cond_def_kind(OPS_last(ops), OP_ALWAYS_COND_DEF);
00537
00538 if ((rtype == MTYPE_U8) && (desc == MTYPE_U4)) {
00539 Build_OP (TOP_dsll32, result, result, Gen_Literal_TN(0, 4), ops);
00540 Build_OP (TOP_dsrl32, result, result, Gen_Literal_TN(0, 4), ops);
00541 }
00542 return;
00543 case MTYPE_I2:
00544 case MTYPE_U2:
00545 if (Target_Byte_Sex == BIG_ENDIAN) {
00546 Build_OP (desc == MTYPE_I2 ? TOP_lb : TOP_lbu,
00547 result, base, disp, ops);
00548 Build_OP (TOP_sll, result, result, Gen_Literal_TN(8, 4), ops);
00549
00550 Adjust_Addr_TNs (TOP_lb, &base, &disp, 1, ops);
00551 tmp = Build_TN_Of_Mtype(rtype);
00552 Build_OP (TOP_lbu, tmp, base, disp, ops);
00553 Build_OP (TOP_or, result, result, tmp, ops);
00554 } else {
00555 tmp = Build_TN_Of_Mtype(rtype);
00556 Build_OP (TOP_lbu, tmp, base, disp, ops);
00557
00558 Adjust_Addr_TNs (TOP_lb, &base, &disp, 1, ops);
00559 Build_OP (desc == MTYPE_I2 ? TOP_lb : TOP_lbu,
00560 result, base, disp, ops);
00561 Build_OP (TOP_sll, result, result, Gen_Literal_TN(8, 4), ops);
00562 Build_OP (TOP_or, result, result, tmp, ops);
00563 }
00564 return;
00565 default:
00566 FmtAssert (FALSE, ("Expand_Composed_Load: unexpected operand size\n"));
00567 }
00568 }
00569 #endif
00570
00571 void
00572 Expand_Misaligned_Load ( OPCODE op, TN *result, TN *base, TN *disp, VARIANT variant, OPS *ops)
00573 {
00574 Expand_Composed_Load ( op, result, base, disp, variant, ops);
00575 }
00576
00577 #ifdef TARG_SL
00578 void
00579 Expand_Composed_Store (TYPE_ID mtype, TN *obj, TN *base, TN *disp, VARIANT variant, OPS *ops)
00580 {
00581 DevWarn ("Expand_Composed_Store: Unaligned store found");
00582 if (MTYPE_is_float(mtype))
00583 {
00584 TN *tmp;
00585 DevWarn ("Float type in Expand_Composed_Load");
00586 if (mtype == MTYPE_F4)
00587 {
00588 Expand_Composed_Store (MTYPE_I4, obj, base, disp, variant, ops);
00589 }
00590 else
00591 {
00592 Expand_Composed_Store (MTYPE_I8, obj, base, disp, variant, ops);
00593 }
00594 return;
00595 }
00596
00597 else {
00598 TN *store1 = Build_TN_Of_Mtype(MTYPE_I4);
00599 TN *store2 = Build_TN_Of_Mtype(MTYPE_I4);
00600 TN *store3 = Build_TN_Of_Mtype(MTYPE_I4);
00601 TN *newbase = Build_TN_Of_Mtype(MTYPE_I4);
00602 switch (mtype) {
00603 case MTYPE_I8:
00604 case MTYPE_U8:
00605
00606 Expand_Add (newbase, base, disp, MTYPE_I4, ops);
00607
00608 Build_OP(TOP_sb, obj, base, disp, ops);
00609
00610 Build_OP(TOP_extrbu, store1, obj, Gen_Literal_TN(15, 4), Gen_Literal_TN(8, 4), ops);
00611 Build_OP(TOP_sb, store1, newbase, Gen_Literal_TN(1, 4), ops);
00612
00613 Build_OP(TOP_extrbu, store2, obj, Gen_Literal_TN(23, 4), Gen_Literal_TN(8, 4), ops);
00614 Build_OP(TOP_sb, store2, newbase, Gen_Literal_TN(2, 4), ops);
00615
00616 Build_OP(TOP_extrbu, store3, obj, Gen_Literal_TN(31, 4), Gen_Literal_TN(8, 4), ops);
00617 Build_OP(TOP_sb, store3, newbase, Gen_Literal_TN(3, 4), ops);
00618
00619 obj = Get_TN_Pair(obj);
00620 FmtAssert(obj != NULL, ("source tn pair in Expand_Composed_Store not setup\n"));
00621
00622 Build_OP(TOP_sb, obj, newbase, Gen_Literal_TN(4, 4), ops);
00623
00624 Build_OP(TOP_extrbu, store1, obj, Gen_Literal_TN(15, 4), Gen_Literal_TN(8, 4), ops);
00625 Build_OP(TOP_sb, store1, newbase, Gen_Literal_TN(5, 4), ops);
00626
00627 Build_OP(TOP_extrbu, store2, obj, Gen_Literal_TN(23, 4), Gen_Literal_TN(8, 4), ops);
00628 Build_OP(TOP_sb, store2, newbase, Gen_Literal_TN(6, 4), ops);
00629
00630 Build_OP(TOP_extrbu, store3, obj, Gen_Literal_TN(31, 4), Gen_Literal_TN(8, 4), ops);
00631 Build_OP(TOP_sb, store3, newbase, Gen_Literal_TN(7, 4), ops);
00632
00633 return;
00634 case MTYPE_I4:
00635 case MTYPE_U4:
00636 Build_OP (TOP_sb, obj, base, disp, ops);
00637
00638 Expand_Add (newbase, base, disp, MTYPE_I4, ops);
00639 Build_OP(TOP_extrbu, store1, obj, Gen_Literal_TN(15, 4), Gen_Literal_TN(8, 4), ops);
00640 Build_OP (TOP_sb, store1, newbase, Gen_Literal_TN(1, 4), ops);
00641
00642 Build_OP(TOP_extrbu, store2, obj, Gen_Literal_TN(23, 4), Gen_Literal_TN(8, 4), ops);
00643 Build_OP (TOP_sb, store2, newbase, Gen_Literal_TN(2, 4), ops);
00644
00645 Build_OP(TOP_extrbu, store3, obj, Gen_Literal_TN(31, 4), Gen_Literal_TN(8, 4), ops);
00646 Build_OP (TOP_sb, store3, newbase, Gen_Literal_TN(3, 4), ops);
00647
00648
00649 return;
00650 case MTYPE_I2:
00651 case MTYPE_U2:
00652 Build_OP (TOP_sb, obj, base, disp, ops);
00653
00654 Expand_Add (newbase, base, disp, MTYPE_I4, ops);
00655 Build_OP(TOP_extrbu, store1, obj, Gen_Literal_TN(15, 4), Gen_Literal_TN(8, 4), ops);
00656 Build_OP (TOP_sb, store1, newbase, Gen_Literal_TN(1, 4), ops);
00657 return;
00658 default:
00659 FmtAssert (FALSE, ("Expand_Composed_Load: unexpected operand size\n"));
00660 }
00661 }
00662 }
00663 #else
00664 static void
00665 Expand_Composed_Store (TYPE_ID mtype, TN *obj, TN *base, TN *disp, VARIANT variant, OPS *ops)
00666 {
00667 if (MTYPE_is_float(mtype))
00668 {
00669 TN *tmp;
00670
00671 if (mtype == MTYPE_F4)
00672 {
00673 tmp = Build_TN_Of_Mtype(MTYPE_I4);
00674 Build_OP ( TOP_mfc1, tmp, obj, ops );
00675 Expand_Composed_Store (MTYPE_I4, tmp, base, disp, variant, ops);
00676 }
00677 else
00678 {
00679 tmp = Build_TN_Of_Mtype(MTYPE_I8);
00680 Build_OP ( TOP_dmfc1, tmp, obj, ops );
00681 Expand_Composed_Store (MTYPE_I8, tmp, base, disp, variant, ops);
00682 }
00683 return;
00684 }
00685 FmtAssert (FALSE, ("Expand_Composed_Store: unexpected instruction (sdr)\n"));
00686 TN *tmp;
00687 switch (mtype) {
00688 case MTYPE_I8:
00689 case MTYPE_U8:
00690 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_sdl : TOP_sdr,
00691 obj, base, disp, ops);
00692
00693 Adjust_Addr_TNs (Target_Byte_Sex == BIG_ENDIAN ? TOP_sdr : TOP_sdl,
00694 &base, &disp, 7, ops);
00695 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_sdr : TOP_sdl,
00696 obj, base, disp, ops);
00697 return;
00698 case MTYPE_I4:
00699 case MTYPE_U4:
00700 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_swl : TOP_swr,
00701 obj, base, disp, ops);
00702
00703 Adjust_Addr_TNs (Target_Byte_Sex == BIG_ENDIAN ? TOP_swr : TOP_swl,
00704 &base, &disp, 3, ops);
00705 Build_OP (Target_Byte_Sex == BIG_ENDIAN ? TOP_swr : TOP_swl,
00706 obj, base, disp, ops);
00707 return;
00708 case MTYPE_I2:
00709 case MTYPE_U2:
00710 if (Target_Byte_Sex == BIG_ENDIAN) {
00711 tmp = Build_TN_Of_Mtype(mtype);
00712 Build_OP (TOP_srl, tmp, obj, Gen_Literal_TN(8, 4), ops);
00713 Build_OP (TOP_sb, tmp, base, disp, ops);
00714
00715 Adjust_Addr_TNs (TOP_lb, &base, &disp, 1, ops);
00716 Build_OP (TOP_sb, obj, base, disp, ops);
00717 } else {
00718 Build_OP (TOP_sb, obj, base, disp, ops);
00719
00720 Adjust_Addr_TNs (TOP_lb, &base, &disp, 1, ops);
00721 tmp = Build_TN_Of_Mtype(mtype);
00722 Build_OP (TOP_srl, tmp, obj, Gen_Literal_TN(8, 4), ops);
00723 Build_OP (TOP_sb, tmp, base, disp, ops);
00724 }
00725 return;
00726 default:
00727 FmtAssert (FALSE, ("Expand_Composed_Load: unexpected operand size\n"));
00728 }
00729 }
00730 #endif
00731
00732 void
00733 Expand_Misaligned_Store (TYPE_ID mtype, TN *obj_tn, TN *base_tn, TN *disp_tn, VARIANT variant, OPS *ops)
00734 {
00735 Expand_Composed_Store (mtype, obj_tn, base_tn, disp_tn, variant, ops);
00736 }
00737
00738
00739 BOOL Is_Stack_Used(void)
00740 {
00741 return FALSE;
00742 }
00743
00744 #ifdef TARG_SL
00745
00746
00747
00748
00749
00750
00751 TN_RELOCS
00752 Get_Internal_Buf_Reloc_Type( ST* st, INTRINSIC id) {
00753 TN_RELOCS reloc = TN_RELOC_NONE;
00754 Is_True((ST_in_vbuf(st) || ST_in_sbuf(st)), (" Passing a non-vbuf variable to Get_Vbuf_Reloc_Type"));
00755 if( id == INTRN_VBUF_OFFSET || id==INTRN_SBUF_OFFSET ) {
00756 if(ST_in_v1buf(st)) return TN_RELOC_GPREL_V1_15;
00757 else if(ST_in_v2buf(st)) return TN_RELOC_GPREL_V2_15;
00758 else if(ST_in_v4buf(st)) return TN_RELOC_GPREL_V4_15;
00759 else return TN_RELOC_GPREL_S;
00760 }
00761 }
00762 #endif
00763
00764
00765 #ifdef TARG_SL
00766 static void
00767 Exp_Ldst (
00768 OPCODE opcode,
00769 TN *tn,
00770 ST *sym,
00771 INT64 ofst,
00772 BOOL indirect_call,
00773 BOOL is_store,
00774 BOOL is_load,
00775 OPS *ops,
00776 VARIANT variant,
00777 BOOL is_internal_mem_ofst = FALSE)
00778 #else
00779 static void
00780 Exp_Ldst (
00781 OPCODE opcode,
00782 TN *tn,
00783 ST *sym,
00784 INT64 ofst,
00785 BOOL indirect_call,
00786 BOOL is_store,
00787 BOOL is_load,
00788 OPS *ops,
00789 VARIANT variant)
00790 #endif
00791 {
00792 ST *base_sym;
00793 INT64 base_ofst;
00794 TN *base_tn;
00795 TN *ofst_tn;
00796 TN *tmp_tn;
00797 BOOL is_lda = (!is_load && !is_store);
00798 OPS newops;
00799 OP *op;
00800 OPS_Init(&newops);
00801
00802 if (Trace_Exp2) {
00803 fprintf(TFile, "exp_ldst %s: ", OPCODE_name(opcode));
00804 if (tn) Print_TN(tn,FALSE);
00805 if (is_store) fprintf(TFile, " -> ");
00806 else fprintf(TFile, " <- ");
00807 if (ST_class(sym) != CLASS_CONST)
00808 fprintf(TFile, "%lld (%s)\n", ofst, ST_name(sym));
00809 else
00810 fprintf(TFile, "%lld ()\n", ofst);
00811 }
00812
00813 Allocate_Object(sym);
00814
00815 Base_Symbol_And_Offset_For_Addressing (sym, ofst, &base_sym, &base_ofst);
00816
00817 if (base_sym == SP_Sym || base_sym == FP_Sym) {
00818 base_tn = (base_sym == SP_Sym) ? SP_TN : FP_TN;
00819 if (sym == base_sym) {
00820
00821
00822 if (ISA_LC_Value_In_Class(base_ofst, LC_simm16))
00823 ofst_tn = Gen_Literal_TN (base_ofst, 4);
00824 else {
00825 tmp_tn = Build_TN_Of_Mtype(Pointer_Mtype);
00826 Build_OP(TOP_lui, tmp_tn,
00827 Gen_Literal_TN(base_ofst >> 16, 4), &newops);
00828 Build_OP(Use_32_Bit_Pointers ? TOP_addu : TOP_daddu, tmp_tn,
00829 tmp_tn, base_tn, &newops);
00830 base_tn = tmp_tn;
00831 ofst_tn = Gen_Literal_TN (base_ofst & 0xffff, 4);
00832 }
00833 }
00834 else {
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844 if (ISA_LC_Value_In_Class(base_ofst, LC_simm16))
00845 ofst_tn = Gen_Symbol_TN (sym, ofst, 0);
00846 else {
00847 tmp_tn = Build_TN_Of_Mtype(Pointer_Mtype);
00848 Build_OP(TOP_lui, tmp_tn,
00849 Gen_Symbol_TN(sym, ofst, TN_RELOC_HIGH16), &newops);
00850 Build_OP(Use_32_Bit_Pointers ? TOP_addu : TOP_daddu, tmp_tn,
00851 tmp_tn, base_tn, &newops);
00852 base_tn = tmp_tn;
00853 ofst_tn = Gen_Symbol_TN(sym, ofst, TN_RELOC_LOW16);
00854 }
00855 }
00856 }
00857 else if ((ST_class(base_sym) == CLASS_BLOCK || ST_class(base_sym)==CLASS_VAR)
00858 && ST_gprel(base_sym))
00859 {
00860
00861 PU_References_GP = TRUE;
00862
00863 if (ISA_LC_Value_In_Class(base_ofst, LC_simm16)) {
00864 base_tn = GP_TN;
00865
00866 #ifdef TARG_SL
00867 if (is_internal_mem_ofst && ST_in_vbuf(sym)) {
00868 base_tn = Zero_TN;
00869 ofst_tn = Gen_Symbol_TN(sym, ofst, TN_RELOC_GPREL_SL2_V15);
00870 Set_TN_is_v1buf_addr(tn);
00871 }
00872 else if ( is_internal_mem_ofst && ST_in_sbuf(sym) ) {
00873 base_tn = Zero_TN;
00874 ofst_tn = Gen_Symbol_TN(sym, ofst, TN_RELOC_GPREL_S);
00875 }
00876 else
00877 #endif
00878 ofst_tn = Gen_Symbol_TN (sym, ofst, TN_RELOC_GPREL16);
00879 }
00880 else {
00881 FmtAssert(FALSE, ("gp-relative offset doesn't fit in 16 bits"));
00882 }
00883 }
00884 else if (! Gen_PIC_Shared) {
00885 base_tn = Build_TN_Of_Mtype(Pointer_Mtype);
00886 Build_OP(TOP_lui, base_tn,
00887 Gen_Symbol_TN(base_sym, base_ofst, TN_RELOC_HIGH16), &newops);
00888 ofst_tn = Gen_Symbol_TN(base_sym, base_ofst, TN_RELOC_LOW16);
00889 }
00890 else if (Guaranteed_Small_GOT) {
00891 TN *tmp2;
00892 if (! ST_is_export_local(base_sym) &&
00893 ! ISA_LC_Value_In_Class(base_ofst, LC_simm16)) {
00894 tmp2 = Build_TN_Of_Mtype (Pointer_Mtype);
00895 Expand_Load (
00896
00897 OPCODE_make_signed_op(OPR_LDID, Pointer_Mtype, Pointer_Mtype, FALSE),
00898 tmp2, GP_TN, Gen_Symbol_TN(base_sym, base_ofst, TN_RELOC_GOT_PAGE),
00899 &newops);
00900
00901 Set_OP_no_alias(OPS_last(&newops));
00902 base_tn = tmp2;
00903
00904 ofst_tn = Gen_Symbol_TN(base_sym, base_ofst, TN_RELOC_GOT_OFST);
00905 }
00906 else {
00907 if (is_lda && OFFSET_LO(base_ofst) == 0) {
00908
00909 tmp2 = tn;
00910 is_lda = FALSE;
00911 }
00912 else tmp2 = Build_TN_Of_Mtype (Pointer_Mtype);
00913 Expand_Load (
00914
00915 OPCODE_make_signed_op(OPR_LDID, Pointer_Mtype, Pointer_Mtype, FALSE),
00916 tmp2, GP_TN,
00917 Gen_Symbol_TN(base_sym, OFFSET_HI(base_ofst), TN_RELOC_GOT_DISP),
00918 &newops);
00919
00920 Set_OP_no_alias(OPS_last(&newops));
00921 base_tn = tmp2;
00922
00923 ofst_tn = Gen_Literal_TN(OFFSET_LO(base_ofst), 4);
00924 }
00925 }
00926 else {
00927 FmtAssert(FALSE, ("NYI: Exp_Ldst"));
00928 }
00929
00930 if (is_store) {
00931 if (variant == 0)
00932 Expand_Store (OPCODE_desc(opcode), tn, base_tn, ofst_tn, &newops);
00933 else
00934 Expand_Misaligned_Store (OPCODE_desc(opcode), tn,
00935 base_tn, ofst_tn, variant, &newops);
00936 }
00937 else if (is_load) {
00938 if (variant == 0)
00939 Expand_Load (opcode, tn, base_tn, ofst_tn, &newops);
00940 else
00941 Expand_Misaligned_Load (opcode, tn,
00942 base_tn, ofst_tn, variant, &newops);
00943 }
00944 else if (is_lda) {
00945 if (TN_is_symbol(ofst_tn))
00946 Build_OP(Use_32_Bit_Pointers?TOP_addiu:TOP_daddiu,
00947 tn, base_tn, ofst_tn, &newops);
00948 else Expand_Add (tn, ofst_tn, base_tn, OPCODE_rtype(opcode), &newops);
00949 }
00950
00951 FOR_ALL_OPS_OPs (&newops, op) {
00952 if (is_load && ST_is_constant(sym) && OP_load(op)) {
00953
00954
00955
00956 Set_OP_no_alias(op);
00957 }
00958 if (Trace_Exp2) {
00959 fprintf(TFile, "exp_ldst into "); Print_OP (op);
00960 }
00961 }
00962
00963 OPS_Append_Ops(ops, &newops);
00964 }
00965
00966 #ifdef TARG_SL
00967 void Exp_Lda (
00968 TYPE_ID mtype,
00969 TN *tgt_tn,
00970 ST *sym,
00971 INT64 ofst,
00972 OPERATOR call_opr,
00973 OPS *ops,
00974 BOOL is_internal_mem_ofst)
00975 #else
00976 void Exp_Lda (
00977 TYPE_ID mtype,
00978 TN *tgt_tn,
00979 ST *sym,
00980 INT64 ofst,
00981 OPERATOR call_opr,
00982 OPS *ops)
00983 #endif
00984 {
00985 OPCODE opcode = OPCODE_make_op(OPR_LDA, mtype, MTYPE_V);
00986 #ifdef TARG_SL
00987 Exp_Ldst (opcode, tgt_tn, sym, ofst,
00988 (call_opr == OPR_ICALL),
00989 FALSE, FALSE, ops, 0, is_internal_mem_ofst);
00990 #else
00991 Exp_Ldst (opcode, tgt_tn, sym, ofst,
00992 (call_opr == OPR_ICALL),
00993 FALSE, FALSE, ops, 0);
00994 #endif
00995 }
00996
00997 void
00998 Exp_Load (
00999 TYPE_ID rtype,
01000 TYPE_ID desc,
01001 TN *tgt_tn,
01002 ST *sym,
01003 INT64 ofst,
01004 OPS *ops,
01005 VARIANT variant)
01006 {
01007 OPCODE opcode = OPCODE_make_op (OPR_LDID, rtype, desc);
01008 Exp_Ldst (opcode, tgt_tn, sym, ofst, FALSE, FALSE, TRUE, ops, variant);
01009 }
01010
01011 void
01012 Exp_Store (
01013 TYPE_ID mtype,
01014 TN *src_tn,
01015 ST *sym,
01016 INT64 ofst,
01017 OPS *ops,
01018 VARIANT variant)
01019 {
01020 OPCODE opcode = OPCODE_make_op(OPR_STID, MTYPE_V, mtype);
01021 Exp_Ldst (opcode, src_tn, sym, ofst, FALSE, TRUE, FALSE, ops, variant);
01022 }
01023
01024 static ISA_ENUM_CLASS_VALUE
01025 Pick_Prefetch_Hint (VARIANT variant)
01026 {
01027 UINT32 pf_flags = V_pf_flags(variant);
01028 if (PF_GET_READ(pf_flags)) {
01029 if (PF_GET_STRIDE_1L(pf_flags))
01030 return ECV_pfhint_L1_load;
01031 else return ECV_pfhint_L2_load;
01032 }
01033 else {
01034 if (PF_GET_STRIDE_1L(pf_flags))
01035 return ECV_pfhint_L1_store;
01036 else return ECV_pfhint_L2_store;
01037 }
01038 }
01039
01040 void Exp_Prefetch (TOP opc, TN *src1, TN *src2, VARIANT variant, OPS* ops)
01041 {
01042 ISA_ENUM_CLASS_VALUE pfhint;
01043 FmtAssert(opc == TOP_UNDEFINED,
01044 ("Prefetch opcode should be selected in Exp_Prefetch"));
01045 pfhint = Pick_Prefetch_Hint(variant);
01046 Build_OP(TOP_pref, Gen_Enum_TN(pfhint), src1, src2, ops);
01047 }
01048
01049
01050
01051
01052 #if defined(TARG_SL)
01053 void Build_Extrb_OP(TYPE_ID desc, TYPE_ID rtype, TN *tgt_tn, TN *src_tn,
01054 UINT pos, UINT width, OPS *ops)
01055 {
01056 if (width == 32) {
01057 FmtAssert(pos == 31, ("Build_Extrb_OP: pos is out of range\n"));
01058 Expand_Copy(tgt_tn, src_tn, MTYPE_U4, ops);
01059 } else {
01060 if (MTYPE_signed(desc)) {
01061 Build_OP(TOP_extrbs, tgt_tn, src_tn, Gen_Literal_TN(pos, 4),
01062 Gen_Literal_TN(width, 4), ops);
01063 } else {
01064 Build_OP(TOP_extrbu, tgt_tn, src_tn, Gen_Literal_TN(pos, 4),
01065 Gen_Literal_TN(width, 4), ops);
01066 }
01067 }
01068 }
01069
01070 void Build_Extrbu_OP(TYPE_ID desc, TYPE_ID rtype, TN *tgt_tn, TN *src_tn,
01071 UINT pos, UINT width, OPS *ops)
01072 {
01073 if (width == 32) {
01074 FmtAssert(pos == 31, ("Build_Extrbu_OP: pos is out of range\n"));
01075 Expand_Copy(tgt_tn, src_tn, MTYPE_U4, ops);
01076 } else {
01077 Build_OP(TOP_extrbu, tgt_tn, src_tn, Gen_Literal_TN(pos, 4),
01078 Gen_Literal_TN(width, 4), ops);
01079 }
01080 }
01081 void Build_Depb_OP(TYPE_ID desc, TYPE_ID rtype, TN *tgt_tn, TN *src_tn,
01082 UINT pos, UINT width, OPS *ops)
01083 {
01084 if (width == 32) {
01085 FmtAssert(pos == 31, ("Build_Extrb_OP: pos is out of range\n"));
01086 Expand_Copy(tgt_tn, src_tn, MTYPE_U4, ops);
01087 } else {
01088 Build_OP(TOP_depb, tgt_tn, tgt_tn, src_tn, Gen_Literal_TN(pos, 4),
01089 Gen_Literal_TN(width, 4), ops);
01090 }
01091 }
01092
01093 extern TN *
01094 Get_64Bit_High_TN(TN *low, TYPE_ID type, OPS * ops);
01095
01096 void
01097 Exp_Extract_Bits (TYPE_ID rtype, TYPE_ID desc, UINT bit_offset, UINT bit_size,
01098 TN *tgt_tn, TN *src_tn, OPS *ops)
01099 {
01100 FmtAssert(bit_size != 0, ("Exp_Extract_Bits: size of bit field cannot be 0"));
01101 FmtAssert((bit_offset + bit_size) <= MTYPE_bit_size(desc),
01102 ("Exp_Extract_Bits : Not valid bit_offset %d or bit_size %d", bit_offset, bit_size));
01103
01104 if (!MTYPE_is_longlong(rtype)) {
01105 if (!MTYPE_is_longlong(desc)) {
01106 UINT pos = (bit_offset + bit_size) - 1;
01107 UINT width = bit_size;
01108 Build_Extrb_OP(desc, rtype, tgt_tn, src_tn, pos, width, ops);
01109 } else {
01110 TN *src_high = Get_TN_Pair(src_tn);
01111 FmtAssert(src_high, ("Exp_Extract_Bits : I4 <- I8 bit source tn pair not setup"));
01112
01113 if (bit_offset < 32) {
01114 if (bit_offset + bit_size <= 32) {
01115 UINT pos = bit_offset + bit_size - 1;
01116 UINT width = bit_size;
01117 Build_Extrb_OP(desc, rtype, tgt_tn, src_tn, pos, width, ops);
01118 } else {
01119 UINT low_pos = 31;
01120 UINT low_width = 32 - bit_offset;
01121 Build_Extrb_OP(desc, rtype, tgt_tn, src_tn, low_pos, low_width, ops);
01122
01123 UINT high_pos = bit_size-1;
01124 UINT high_width = bit_size + bit_offset - 32;
01125 Build_Depb_OP(desc, rtype, tgt_tn, src_high, high_pos, high_width, ops);
01126 }
01127 } else {
01128 UINT pos = bit_offset + bit_size - 33;
01129 UINT width = bit_size;
01130 Build_Extrb_OP(desc, rtype, tgt_tn, src_high, pos, width, ops);
01131 }
01132 }
01133 } else {
01134 TN *tgt_high = Get_TN_Pair(tgt_tn);
01135 FmtAssert(tgt_high != NULL, ("Exp_Extract_Bits : to I8 result tn pair not setup"));
01136
01137 if (!MTYPE_is_longlong(desc)) {
01138 UINT pos = bit_offset + bit_size - 1;
01139 UINT width = bit_size;
01140
01141 Build_Extrb_OP(desc, rtype, tgt_tn, src_tn, pos, width, ops);
01142 tgt_high = Get_64Bit_High_TN(tgt_tn, desc, ops);
01143 } else {
01144
01145 TN *src_high = Get_TN_Pair(src_tn);
01146 FmtAssert(src_high != NULL, ("Exp_Extract_Bits : I8 <- I8 source tn pair not setup"));
01147
01148 if (bit_offset < 32){
01149 if (bit_offset + bit_size <= 32) {
01150 UINT pos = bit_offset+bit_size - 1;
01151 UINT width = bit_size;
01152
01153 Build_Extrb_OP(desc, rtype, tgt_tn, src_tn, pos, width, ops);
01154 tgt_high = Get_64Bit_High_TN(tgt_tn, desc, ops);
01155 } else {
01156 if (bit_size <= 32) {
01157 UINT low_pos = 31;
01158 UINT low_width = 32 - bit_offset;
01159 Build_Extrb_OP(desc, rtype, tgt_tn, src_tn, low_pos, low_width, ops);
01160
01161 UINT high_pos = bit_size-1;
01162 UINT high_width = bit_size + bit_offset - 32;
01163 Build_Depb_OP(desc, rtype, tgt_tn, src_high, high_pos, high_width, ops);
01164
01165 tgt_high = Get_64Bit_High_TN(tgt_tn, desc, ops);
01166 } else {
01167
01168 UINT pos_1 = 31;
01169 UINT width_1 = 32 - bit_offset;
01170 Build_Extrbu_OP(desc, rtype, tgt_tn, src_tn, pos_1, width_1, ops);
01171
01172 if (bit_offset != 0) {
01173 UINT pos_2 = 31;
01174 UINT width_2 = bit_offset;
01175 Build_Depb_OP(desc, rtype, tgt_tn, src_high, pos_2, width_2, ops);
01176 }
01177
01178 UINT pos_3 = bit_size + bit_offset - 32 - 1;
01179 UINT width_3 = bit_size - 32;
01180 Build_Extrb_OP(desc, rtype, tgt_high, src_high, pos_3, width_3, ops);
01181 }
01182 }
01183 } else {
01184
01185 UINT pos = bit_offset + bit_size -33;
01186 UINT width = bit_size;
01187
01188 Build_Extrb_OP(desc, rtype, tgt_tn, src_high, pos, width, ops);
01189 tgt_high = Get_64Bit_High_TN(tgt_tn, desc, ops);
01190 }
01191 }
01192 }
01193 }
01194 #else
01195 void
01196 Exp_Extract_Bits (TYPE_ID rtype, TYPE_ID desc, UINT bit_offset, UINT bit_size,
01197 TN *tgt_tn, TN *src_tn, OPS *ops)
01198 {
01199 TN *tmp1_tn = Build_TN_Like (tgt_tn);
01200 UINT pos = (Target_Byte_Sex == BIG_ENDIAN || CG_emit_non_gas_syntax)
01201 ? MTYPE_bit_size(desc)-bit_offset-bit_size : bit_offset;
01202 if (pos == 0 && bit_size <= 16 && ! MTYPE_signed(rtype)) {
01203 Build_OP(TOP_andi, tgt_tn, src_tn,
01204 Gen_Literal_TN((1 << bit_size)-1, 4), ops);
01205 return;
01206 }
01207
01208 TOP left_shift_op = TOP_sll;
01209 INT left_shift_amt = MTYPE_bit_size(rtype) - pos - bit_size;
01210 if (MTYPE_is_size_double(rtype)) {
01211 left_shift_op = TOP_dsll;
01212 if (left_shift_amt > 31) {
01213 left_shift_op = TOP_dsll32;
01214 left_shift_amt -= 32;
01215 }
01216 }
01217 Build_OP(left_shift_op, tmp1_tn, src_tn, Gen_Literal_TN(left_shift_amt, 4),
01218 ops);
01219 TOP right_shift_op = TOP_sra;
01220 INT right_shift_amt = MTYPE_bit_size(rtype) - bit_size;
01221 if (MTYPE_is_size_double(rtype)) {
01222 right_shift_op = TOP_dsra;
01223 if (right_shift_amt > 31) {
01224 right_shift_op = TOP_dsra32;
01225 right_shift_amt -= 32;
01226 }
01227 }
01228 if (! MTYPE_signed(rtype)) {
01229 if (right_shift_op == TOP_sra)
01230 right_shift_op = TOP_srl;
01231 else if (right_shift_op == TOP_dsra)
01232 right_shift_op = TOP_dsrl;
01233 else right_shift_op = TOP_dsrl32;
01234 }
01235 Build_OP(right_shift_op, tgt_tn, tmp1_tn, Gen_Literal_TN(right_shift_amt, 4),
01236 ops);
01237 }
01238 #endif
01239
01240
01241
01242
01243
01244 #if defined(TARG_SL)
01245 void
01246 Exp_Deposit_Bits (TYPE_ID rtype, TYPE_ID desc, UINT bit_offset, UINT bit_size,
01247 TN *tgt_tn, TN *src1_tn, TN *src2_tn, OPS *ops)
01248 {
01249 FmtAssert(bit_size != 0, ("Exp_Deposit_Bits: size of bit field cannot be 0"));
01250 FmtAssert(bit_offset + bit_size <= MTYPE_bit_size(rtype), ("Exp_Deposit_Bits : bit out of range"));
01251
01252 if (tgt_tn!=src1_tn) {
01253 Expand_Add(tgt_tn, src1_tn, Zero_TN, rtype, ops);
01254 }
01255
01256 if (!MTYPE_is_longlong(rtype)) {
01257
01258 UINT pos = bit_offset + bit_size - 1;
01259 UINT width = bit_size;
01260 Build_Depb_OP(desc, rtype, tgt_tn, src2_tn, pos, width, ops);
01261 } else {
01262 TN *tgt_high = Get_TN_Pair(tgt_tn);
01263 TN *src1_high = Get_TN_Pair(src1_tn);
01264
01265 FmtAssert(tgt_high != NULL, ("Exp_Deposit_Bits : I8 <- I4 source1 tn pair not setup"));
01266
01267 if (src1_high != NULL)
01268 Expand_Add(tgt_high, src1_high, Zero_TN, MTYPE_U4, ops);
01269
01270 if (!MTYPE_is_longlong(desc)) {
01271 if (bit_offset < 32) {
01272 if (bit_offset + bit_size <= 32) {
01273 UINT pos = bit_offset + bit_size - 1;
01274 UINT width = bit_size;
01275
01276 Build_Depb_OP(desc, rtype, tgt_tn, src2_tn, pos, width, ops);
01277
01278 } else {
01279
01280 UINT low_pos = 31;
01281 UINT low_width = 32 - bit_offset;
01282 Build_Depb_OP(desc, rtype, tgt_tn, src2_tn, low_pos, low_width, ops);
01283
01284 UINT high_pos = bit_offset + bit_size - 33;
01285 UINT high_width = bit_offset + bit_size - 32;
01286 TN *temp_tn = Build_TN_Like(src2_tn);
01287 Build_OP(TOP_srl, temp_tn, src2_tn, Gen_Literal_TN(low_width, 4), ops);
01288
01289 Build_Depb_OP(desc, rtype, tgt_tn, temp_tn, high_pos, high_width, ops);
01290 }
01291 } else {
01292
01293 UINT pos = bit_offset + bit_size - 33;
01294 UINT width = bit_size;
01295 Build_Depb_OP(desc, rtype, tgt_high, src2_tn, pos, width, ops);
01296 }
01297 } else {
01298 TN *src2_high = Get_TN_Pair(src2_tn);
01299 if (bit_offset < 32) {
01300 if (bit_offset + bit_size <= 32) {
01301 UINT pos = bit_offset + bit_size - 1;
01302 UINT width = bit_size;
01303 Build_Depb_OP(desc, rtype, tgt_tn, src2_tn, pos, width, ops);
01304 } else {
01305 if (bit_size <= 32) {
01306 UINT low_pos = 31;
01307 UINT low_width = 32 - bit_offset;
01308
01309 Build_Depb_OP(desc, rtype, tgt_tn, src2_tn, low_pos, low_width, ops);
01310
01311 UINT high_pos = bit_offset + bit_size - 33;
01312 UINT high_width = bit_offset + bit_size - 32;
01313 TN *temp_tn = Build_TN_Like(src2_tn);
01314
01315 Build_OP(TOP_srl, temp_tn, src2_tn, Gen_Literal_TN(low_width, 4), ops);
01316 Build_Depb_OP(desc, rtype, tgt_high, temp_tn, high_pos, high_width, ops);
01317
01318 } else {
01319
01320
01321 FmtAssert(src2_high != NULL, ("Exp_Deposit_Bits : I8 <- I8 source2 tn pair not setup"));
01322
01323 UINT pos_1 = 31;
01324 UINT width_1 = 32-bit_offset;
01325
01326 Build_Depb_OP(desc, rtype, tgt_tn, src2_tn, pos_1, width_1, ops);
01327
01328 if (bit_offset != 0) {
01329 UINT pos_2 = bit_offset-1;
01330 UINT width_2 = bit_offset;
01331 TN *temp_tn = Build_TN_Like(src2_tn);
01332
01333 Build_OP(TOP_srl, temp_tn, src2_tn, Gen_Literal_TN(width_1, 4), ops);
01334 Build_Depb_OP(desc, rtype, tgt_high, temp_tn, pos_2, width_2, ops);
01335 }
01336
01337 UINT pos_3 = bit_offset + bit_size -33;
01338 UINT width_3 = bit_size - 32;
01339
01340 Build_Depb_OP(desc, rtype, tgt_high, src2_high, pos_3, width_3, ops);
01341 }
01342 }
01343 } else {
01344
01345 UINT pos = bit_offset + bit_size - 33;
01346 UINT width = bit_size;
01347
01348 Build_Depb_OP(desc, rtype, tgt_high, src2_tn, pos, width, ops);
01349 }
01350 }
01351 }
01352 }
01353 #else
01354 void
01355 Exp_Deposit_Bits (TYPE_ID rtype, TYPE_ID desc, UINT bit_offset, UINT bit_size,
01356 TN *tgt_tn, TN *src1_tn, TN *src2_tn, OPS *ops)
01357 {
01358 FmtAssert(bit_size != 0, ("size of bit field cannot be 0"));
01359
01360 UINT targ_bit_offset = bit_offset;
01361 if (Target_Byte_Sex == BIG_ENDIAN) {
01362 targ_bit_offset = MTYPE_bit_size(desc) - bit_offset - bit_size;
01363 }
01364 TN *tmp1_tn = Build_TN_Like (src1_tn);
01365 TOP shift_op = TOP_srl;
01366 INT shift_amt = targ_bit_offset;
01367 if (MTYPE_is_size_double(rtype)) {
01368 shift_op = TOP_dsrl;
01369 if (shift_amt > 31) {
01370 shift_op = TOP_dsrl32;
01371 shift_amt -= 32;
01372 }
01373 }
01374 Build_OP(shift_op, tmp1_tn, src1_tn, Gen_Literal_TN(shift_amt,4), ops);
01375 Build_OP(TOP_xor, tmp1_tn, tmp1_tn, src2_tn, ops);
01376 shift_op = TOP_sll;
01377 shift_amt = MTYPE_bit_size(rtype) - bit_size;
01378 if (MTYPE_is_size_double(rtype)) {
01379 shift_op = TOP_dsll;
01380 if (shift_amt > 31) {
01381 shift_op = TOP_dsll32;
01382 shift_amt -= 32;
01383 }
01384 }
01385 Build_OP(shift_op, tmp1_tn, tmp1_tn, Gen_Literal_TN(shift_amt, 4), ops);
01386 shift_op = TOP_srl;
01387 shift_amt = MTYPE_bit_size(rtype) - bit_size - targ_bit_offset;
01388 if (MTYPE_is_size_double(rtype)) {
01389 shift_op = TOP_dsrl;
01390 if (shift_amt > 31) {
01391 shift_op = TOP_dsrl32;
01392 shift_amt -= 32;
01393 }
01394 }
01395 Build_OP(shift_op, tmp1_tn, tmp1_tn, Gen_Literal_TN(shift_amt, 4), ops);
01396 Build_OP(TOP_xor, tgt_tn, src1_tn, tmp1_tn, ops);
01397 }
01398 #endif
01399
01400 void
01401 Expand_Lda_Label (TN *dest, TN *lab, OPS *ops)
01402 {
01403 Set_TN_is_reloc_got_disp(lab);
01404 if (Use_32_Bit_Pointers)
01405 Build_OP(TOP_lw, dest, GP_TN, lab, ops);
01406 else
01407 Build_OP(TOP_ld, dest, GP_TN, lab, ops);
01408 }