Adjust NativeCall for patchable_set48 on MIPS CPUs.

Sun, 05 Mar 2017 13:20:40 -0500

author
fujie
date
Sun, 05 Mar 2017 13:20:40 -0500
changeset 366
47e82298518d
parent 365
9436e4b25599
child 367
826b64c07856

Adjust NativeCall for patchable_set48 on MIPS CPUs.

src/cpu/mips/vm/assembler_mips.cpp file | annotate | diff | comparison | revisions
src/cpu/mips/vm/mips_64.ad file | annotate | diff | comparison | revisions
src/cpu/mips/vm/nativeInst_mips.cpp file | annotate | diff | comparison | revisions
src/cpu/mips/vm/nativeInst_mips.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/mips/vm/assembler_mips.cpp	Wed Mar 22 10:12:55 2017 +0800
     1.2 +++ b/src/cpu/mips/vm/assembler_mips.cpp	Sun Mar 05 13:20:40 2017 -0500
     1.3 @@ -1082,7 +1082,7 @@
     1.4  
     1.5  void MacroAssembler::ic_call(address entry) {
     1.6  	RelocationHolder rh = virtual_call_Relocation::spec(pc());
     1.7 -	li64(IC_Klass, (long)Universe::non_oop_word());
     1.8 +	patchable_set48(IC_Klass, (long)Universe::non_oop_word());
     1.9  	assert(entry != NULL, "call most probably wrong");
    1.10  	InstructionMark im(this);
    1.11  	relocate(rh);
     2.1 --- a/src/cpu/mips/vm/mips_64.ad	Wed Mar 22 10:12:55 2017 +0800
     2.2 +++ b/src/cpu/mips/vm/mips_64.ad	Sun Mar 05 13:20:40 2017 -0500
     2.3 @@ -865,7 +865,7 @@
     2.4  // The address of the call instruction needs to be 16-byte aligned to
     2.5  // ensure that it does not span a cache line so that it can be patched.
     2.6  int CallDynamicJavaDirectNode::compute_padding(int current_offset) const {
     2.7 -  //li64   <--- skip
     2.8 +  //loadIC   <--- skip
     2.9  
    2.10    //lui
    2.11    //ori
    2.12 @@ -875,7 +875,7 @@
    2.13    //jalr
    2.14    //nop
    2.15  
    2.16 -  current_offset += 4 * 6; // skip li64 
    2.17 +  current_offset += 4 * 4;
    2.18    return round_to(current_offset, alignment_required()) - current_offset;
    2.19  }
    2.20  
    2.21 @@ -961,9 +961,6 @@
    2.22  }
    2.23  
    2.24  int MachCallDynamicJavaNode::ret_addr_offset() {
    2.25 -  /* 2012/9/10 Jin: must be kept in sync with Java_Dynamic_Call */
    2.26 -
    2.27 - // return NativeCall::instruction_size; 
    2.28    assert(NativeCall::instruction_size == 24, "in MachCallDynamicJavaNode::ret_addr_offset");
    2.29    //The value ought to be 4 + 16 bytes.
    2.30    //lui IC_Klass,
    2.31 @@ -976,8 +973,7 @@
    2.32    //ori T9
    2.33    //jalr T9
    2.34    //nop
    2.35 -  return 6 * 4 + NativeCall::instruction_size; 
    2.36 -
    2.37 +  return 4 * 4 + NativeCall::instruction_size; 
    2.38  }
    2.39  
    2.40  //=============================================================================
     3.1 --- a/src/cpu/mips/vm/nativeInst_mips.cpp	Wed Mar 22 10:12:55 2017 +0800
     3.2 +++ b/src/cpu/mips/vm/nativeInst_mips.cpp	Sun Mar 05 13:20:40 2017 -0500
     3.3 @@ -119,32 +119,92 @@
     3.4        fatal("not a call");
     3.5    }
     3.6  #else
     3.7 -  /* li64 or li48 */
     3.8 -  int li_64 = 0;
     3.9 -  int li_48 = 0;
    3.10  
    3.11 -  if (  is_op	(Assembler::lui_op) &&
    3.12 +  // li64
    3.13 +  if ( is_op(Assembler::lui_op) &&
    3.14 +	is_op(int_at(4), Assembler::ori_op) &&
    3.15 +	is_special_op(int_at(8), Assembler::dsll_op) &&
    3.16 +	is_op(int_at(12), Assembler::ori_op) &&
    3.17 +	is_special_op(int_at(16), Assembler::dsll_op) &&
    3.18 +	is_op(int_at(20), Assembler::ori_op) &&
    3.19 +        is_special_op(int_at(24), Assembler::jalr_op) ) {
    3.20 +      return;
    3.21 +  }
    3.22 +
    3.23 +  //lui dst, imm16
    3.24 +  //ori dst, dst, imm16
    3.25 +  //dsll dst, dst, 16
    3.26 +  //ori dst, dst, imm16
    3.27 +  if (  is_op(Assembler::lui_op) &&
    3.28  	  is_op	(int_at(4), Assembler::ori_op) &&
    3.29  	  is_special_op(int_at(8), Assembler::dsll_op) &&
    3.30  	  is_op	(int_at(12), Assembler::ori_op) &&
    3.31 -	  is_special_op(int_at(16), Assembler::dsll_op) &&
    3.32 -	  is_op	(int_at(20), Assembler::ori_op) &&
    3.33 -	  is_special_op(int_at(24), Assembler::jalr_op) ) {
    3.34 -      li_64 = 1;
    3.35 +          is_special_op(int_at(16), Assembler::jalr_op) ) {
    3.36 +      return;
    3.37    }
    3.38  
    3.39 -  if (  is_op	(Assembler::lui_op) &&
    3.40 -	  is_op	(int_at(4), Assembler::ori_op) &&
    3.41 -	  is_special_op(int_at(8), Assembler::dsll_op) &&
    3.42 -	  is_op	(int_at(12), Assembler::ori_op) &&
    3.43 -	  is_special_op(int_at(16), Assembler::jalr_op) ) {
    3.44 -      li_48 = 1;
    3.45 +  //ori dst, R0, imm16
    3.46 +  //dsll dst, dst, 16
    3.47 +  //ori dst, dst, imm16
    3.48 +  //nop
    3.49 +  if (  is_op(Assembler::ori_op) &&
    3.50 +	  is_special_op(int_at(4), Assembler::dsll_op) &&
    3.51 +	  is_op	(int_at(8), Assembler::ori_op) &&
    3.52 +          nativeInstruction_at(addr_at(12))->is_nop() &&
    3.53 +          is_special_op(int_at(16), Assembler::jalr_op) ) {
    3.54 +      return;
    3.55    }
    3.56  
    3.57 -  if (!li_64 && !li_48) {
    3.58 -tty->print_cr("NativeCall::verify addr=%lx", addr_at(0));
    3.59 -      fatal("not a call");
    3.60 +  //ori dst, R0, imm16
    3.61 +  //dsll dst, dst, 16
    3.62 +  //nop
    3.63 +  //nop
    3.64 +  if (  is_op(Assembler::ori_op) &&
    3.65 +	  is_special_op(int_at(4), Assembler::dsll_op) &&
    3.66 +	  nativeInstruction_at(addr_at(8))->is_nop()   &&
    3.67 +          nativeInstruction_at(addr_at(12))->is_nop() &&
    3.68 +          is_special_op(int_at(16), Assembler::jalr_op) ) {
    3.69 +      return;
    3.70    }
    3.71 +
    3.72 +  //daddiu dst, R0, imm16
    3.73 +  //nop
    3.74 +  //nop
    3.75 +  //nop
    3.76 +  if (  is_op(Assembler::daddiu_op) &&
    3.77 +	  nativeInstruction_at(addr_at(4))->is_nop() &&
    3.78 +	  nativeInstruction_at(addr_at(8))->is_nop() &&
    3.79 +	  nativeInstruction_at(addr_at(12))->is_nop() &&
    3.80 +          is_special_op(int_at(16), Assembler::jalr_op) ) {
    3.81 +      return;
    3.82 +  }
    3.83 +
    3.84 +  //lui dst, imm16
    3.85 +  //ori dst, dst, imm16
    3.86 +  //nop
    3.87 +  //nop
    3.88 +  if (  is_op(Assembler::lui_op) &&
    3.89 +	  is_op	(int_at(4), Assembler::ori_op) &&
    3.90 +	  nativeInstruction_at(addr_at(8))->is_nop() &&
    3.91 +	  nativeInstruction_at(addr_at(12))->is_nop() && 
    3.92 +          is_special_op(int_at(16), Assembler::jalr_op) ) {
    3.93 +      return;
    3.94 +  }
    3.95 +
    3.96 +  //lui dst, imm16
    3.97 +  //nop
    3.98 +  //nop
    3.99 +  //nop
   3.100 +  if (  is_op(Assembler::lui_op) &&
   3.101 +	  nativeInstruction_at(addr_at(4))->is_nop() &&
   3.102 +	  nativeInstruction_at(addr_at(8))->is_nop() &&
   3.103 +	  nativeInstruction_at(addr_at(12))->is_nop() && 
   3.104 +          is_special_op(int_at(16), Assembler::jalr_op) ) {
   3.105 +      return;
   3.106 +  }
   3.107 +
   3.108 +
   3.109 +  fatal("not a call");
   3.110  #endif
   3.111  }
   3.112  
   3.113 @@ -152,18 +212,135 @@
   3.114  #ifndef _LP64
   3.115    return (address)Assembler::merge(int_at(4)&0xffff, long_at(0)&0xffff);
   3.116  #else
   3.117 -  /* li64 or li48 */
   3.118 -  if (is_special_op(int_at(16), Assembler::dsll_op)) {
   3.119 -    return (address)Assembler::merge( (intptr_t)(int_at(20) & 0xffff), 
   3.120 -				    (intptr_t)(int_at(12) & 0xffff),
   3.121 -				    (intptr_t)(int_at(4) & 0xffff),
   3.122 -				    (intptr_t)(int_at(0) & 0xffff));
   3.123 -  } else if (is_special_op(int_at(16), Assembler::jalr_op)) {
   3.124 -    return (address)Assembler::merge( (intptr_t)(int_at(12) & 0xffff), 
   3.125 -				    (intptr_t)(int_at(4) & 0xffff),
   3.126 -				    (intptr_t)(int_at(0) & 0xffff),
   3.127 -				    (intptr_t)0);
   3.128 +
   3.129 +  // li64
   3.130 +  if ( is_op(Assembler::lui_op) &&
   3.131 +        is_op(int_at(4), Assembler::ori_op) &&
   3.132 +        is_special_op(int_at(8), Assembler::dsll_op) &&
   3.133 +        is_op(int_at(12), Assembler::ori_op) &&
   3.134 +        is_special_op(int_at(16), Assembler::dsll_op) &&
   3.135 +        is_op(int_at(20), Assembler::ori_op) ) {
   3.136 +
   3.137 +      return (address)Assembler::merge( (intptr_t)(int_at(20) & 0xffff),
   3.138 +                               (intptr_t)(int_at(12) & 0xffff),
   3.139 +                               (intptr_t)(int_at(4) & 0xffff),
   3.140 +                               (intptr_t)(int_at(0) & 0xffff));
   3.141    }
   3.142 +
   3.143 +  //lui dst, imm16
   3.144 +  //ori dst, dst, imm16
   3.145 +  //dsll dst, dst, 16
   3.146 +  //ori dst, dst, imm16
   3.147 +  if (  is_op(Assembler::lui_op) &&
   3.148 +          is_op (int_at(4), Assembler::ori_op) &&
   3.149 +          is_special_op(int_at(8), Assembler::dsll_op) &&
   3.150 +          is_op (int_at(12), Assembler::ori_op) ) {
   3.151 +
   3.152 +      return (address)Assembler::merge( (intptr_t)(int_at(12) & 0xffff), 
   3.153 +		               (intptr_t)(int_at(4) & 0xffff),
   3.154 +			       (intptr_t)(int_at(0) & 0xffff),
   3.155 +			       (intptr_t)0);
   3.156 +  }
   3.157 +
   3.158 +  //ori dst, R0, imm16
   3.159 +  //dsll dst, dst, 16
   3.160 +  //ori dst, dst, imm16
   3.161 +  //nop
   3.162 +  if (  is_op(Assembler::ori_op) &&
   3.163 +          is_special_op(int_at(4), Assembler::dsll_op) &&
   3.164 +          is_op (int_at(8), Assembler::ori_op) &&
   3.165 +          nativeInstruction_at(addr_at(12))->is_nop()) {
   3.166 +
   3.167 +      return (address)Assembler::merge( (intptr_t)(int_at(8) & 0xffff),
   3.168 +                               (intptr_t)(int_at(0) & 0xffff),
   3.169 +                               (intptr_t)0,
   3.170 +                               (intptr_t)0);
   3.171 +  }
   3.172 +
   3.173 +  //ori dst, R0, imm16
   3.174 +  //dsll dst, dst, 16
   3.175 +  //nop
   3.176 +  //nop
   3.177 +  if (  is_op(Assembler::ori_op) &&
   3.178 +          is_special_op(int_at(4), Assembler::dsll_op) &&
   3.179 +          nativeInstruction_at(addr_at(8))->is_nop()   &&
   3.180 +          nativeInstruction_at(addr_at(12))->is_nop()) {
   3.181 +
   3.182 +      return (address)Assembler::merge( (intptr_t)(0),
   3.183 +                               (intptr_t)(int_at(0) & 0xffff),
   3.184 +                               (intptr_t)0,
   3.185 +                               (intptr_t)0);
   3.186 +  }
   3.187 +
   3.188 +  //daddiu dst, R0, imm16
   3.189 +  //nop
   3.190 +  //nop
   3.191 +  //nop
   3.192 +  if (  is_op(Assembler::daddiu_op) &&
   3.193 +          nativeInstruction_at(addr_at(4))->is_nop() &&
   3.194 +          nativeInstruction_at(addr_at(8))->is_nop() &&
   3.195 +          nativeInstruction_at(addr_at(12))->is_nop() ) {
   3.196 +
   3.197 +      int sign = int_at(0) & 0x8000;
   3.198 +      if (sign == 0) {
   3.199 +         return (address)Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
   3.200 +                                  (intptr_t)0,
   3.201 +                                  (intptr_t)0,
   3.202 +                                  (intptr_t)0);
   3.203 +      } else {
   3.204 +         return (address)Assembler::merge( (intptr_t)(int_at(0) & 0xffff),
   3.205 +                                  (intptr_t)(0xffff),
   3.206 +                                  (intptr_t)(0xffff),
   3.207 +                                  (intptr_t)(0xffff));
   3.208 +      }
   3.209 +  }
   3.210 +
   3.211 +  //lui dst, imm16
   3.212 +  //ori dst, dst, imm16
   3.213 +  //nop
   3.214 +  //nop
   3.215 +  if (  is_op(Assembler::lui_op) &&
   3.216 +          is_op (int_at(4), Assembler::ori_op) &&
   3.217 +          nativeInstruction_at(addr_at(8))->is_nop() &&
   3.218 +          nativeInstruction_at(addr_at(12))->is_nop() ) {
   3.219 +
   3.220 +      int sign = int_at(0) & 0x8000;
   3.221 +      if (sign == 0) {
   3.222 +         return (address)Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
   3.223 +                                  (intptr_t)(int_at(0) & 0xffff),
   3.224 +                                  (intptr_t)0,
   3.225 +                                  (intptr_t)0);
   3.226 +      } else {
   3.227 +         return (address)Assembler::merge( (intptr_t)(int_at(4) & 0xffff),
   3.228 +                                  (intptr_t)(int_at(0) & 0xffff),
   3.229 +                                  (intptr_t)(0xffff),
   3.230 +                                  (intptr_t)(0xffff));
   3.231 +      }
   3.232 +  }
   3.233 +
   3.234 +  //lui dst, imm16
   3.235 +  //nop
   3.236 +  //nop
   3.237 +  //nop
   3.238 +  if (  is_op(Assembler::lui_op) &&
   3.239 +          nativeInstruction_at(addr_at(4))->is_nop() &&
   3.240 +          nativeInstruction_at(addr_at(8))->is_nop() &&
   3.241 +          nativeInstruction_at(addr_at(12))->is_nop() ) {
   3.242 +
   3.243 +      int sign = int_at(0) & 0x8000;
   3.244 +      if (sign == 0) {
   3.245 +         return (address)Assembler::merge( (intptr_t)0,
   3.246 +                                  (intptr_t)(int_at(0) & 0xffff),
   3.247 +                                  (intptr_t)0,
   3.248 +                                  (intptr_t)0);
   3.249 +      } else {
   3.250 +         return (address)Assembler::merge( (intptr_t)0,
   3.251 +                                  (intptr_t)(int_at(0) & 0xffff),
   3.252 +                                  (intptr_t)(0xffff),
   3.253 +                                  (intptr_t)(0xffff));
   3.254 +      }
   3.255 +  }
   3.256 +
   3.257  #endif
   3.258  }
   3.259  
   3.260 @@ -196,6 +373,146 @@
   3.261    return p;
   3.262  }
   3.263  
   3.264 +void  NativeCall::patch_set48_gs(address dest) {
   3.265 +  jlong value = (jlong) dest;
   3.266 +  int  rt_reg = (int_at(0) & (0x1f << 16));
   3.267 +  int  rs_reg = rt_reg << 5;
   3.268 +  int  rd_reg = rt_reg >> 5;
   3.269 +
   3.270 +  int hi = (int)(value >> 32);
   3.271 +  int lo = (int)(value & ~0);
   3.272 +
   3.273 +  int count = 0;
   3.274 +
   3.275 +  int insts[4] = {0, 0, 0, 0};
   3.276 +
   3.277 +  if (value == lo) {  // 32-bit integer
   3.278 +    if (Assembler::is_simm16(value)) {
   3.279 +      //daddiu(d, R0, value);
   3.280 +      //set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
   3.281 +      insts[count] = (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value);
   3.282 +      count += 1;
   3.283 +    } else {
   3.284 +      //lui(d, split_low(value >> 16));
   3.285 +      //set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
   3.286 +      insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16);
   3.287 +      count += 1;
   3.288 +      if (Assembler::split_low(value)) {
   3.289 +        //ori(d, d, split_low(value));
   3.290 +        //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
   3.291 +        insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
   3.292 +        count += 1;
   3.293 +      }
   3.294 +    }
   3.295 +  } else if (hi == 0) {  // hardware zero-extends to upper 32
   3.296 +      //ori(d, R0, julong(value) >> 16);
   3.297 +      //set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
   3.298 +      insts[count] = (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16);
   3.299 +      count += 1;
   3.300 +      //dsll(d, d, 16);
   3.301 +      //set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
   3.302 +      insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
   3.303 +      count += 1;
   3.304 +      if (Assembler::split_low(value)) {
   3.305 +        //ori(d, d, split_low(value));
   3.306 +        //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
   3.307 +        insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
   3.308 +        count += 1;
   3.309 +      }
   3.310 +  } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
   3.311 +    //lui(d, value >> 32);
   3.312 +    //set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
   3.313 +    insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32);
   3.314 +    count += 1;
   3.315 +    //ori(d, d, split_low(value >> 16));
   3.316 +    //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
   3.317 +    insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16);
   3.318 +    count += 1;
   3.319 +    //dsll(d, d, 16);
   3.320 +    //set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
   3.321 +    insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
   3.322 +    count += 1;
   3.323 +    //ori(d, d, split_low(value));
   3.324 +    //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
   3.325 +    insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
   3.326 +    count += 1;
   3.327 +  } else {
   3.328 +    tty->print_cr("dest = 0x%x", value);
   3.329 +    guarantee(false, "Not supported yet !");
   3.330 +  }
   3.331 +
   3.332 +  for (count; count < 4; count++) {
   3.333 +    //nop();
   3.334 +    //set_int_at(count << 2, 0);
   3.335 +    insts[count] = 0;
   3.336 +  }
   3.337 +
   3.338 +  atomic_store128_ptr func = get_atomic_store128_func();
   3.339 +  (*func)((long *)addr_at(0), 0, *(long *)&insts[0], *(long *)&insts[2]);
   3.340 +}
   3.341 +
   3.342 +void  NativeCall::patch_set48(address dest) {
   3.343 +  jlong value = (jlong) dest;
   3.344 +  int  rt_reg = (int_at(0) & (0x1f << 16));
   3.345 +  int  rs_reg = rt_reg << 5;
   3.346 +  int  rd_reg = rt_reg >> 5;
   3.347 +
   3.348 +  int hi = (int)(value >> 32);
   3.349 +  int lo = (int)(value & ~0);
   3.350 +
   3.351 +  int count = 0;
   3.352 +
   3.353 +  if (value == lo) {  // 32-bit integer
   3.354 +    if (Assembler::is_simm16(value)) {
   3.355 +      //daddiu(d, R0, value);
   3.356 +      set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
   3.357 +      count += 1;
   3.358 +    } else {
   3.359 +      //lui(d, split_low(value >> 16));
   3.360 +      set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
   3.361 +      count += 1;
   3.362 +      if (Assembler::split_low(value)) {
   3.363 +        //ori(d, d, split_low(value));
   3.364 +        set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
   3.365 +        count += 1;
   3.366 +      }
   3.367 +    }
   3.368 +  } else if (hi == 0) {  // hardware zero-extends to upper 32
   3.369 +      //ori(d, R0, julong(value) >> 16);
   3.370 +      set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
   3.371 +      count += 1;
   3.372 +      //dsll(d, d, 16);
   3.373 +      set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
   3.374 +      count += 1;
   3.375 +      if (Assembler::split_low(value)) {
   3.376 +        //ori(d, d, split_low(value));
   3.377 +        set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
   3.378 +        count += 1;
   3.379 +      }
   3.380 +  } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
   3.381 +    //lui(d, value >> 32);
   3.382 +    set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
   3.383 +    count += 1;
   3.384 +    //ori(d, d, split_low(value >> 16));
   3.385 +    set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
   3.386 +    count += 1;
   3.387 +    //dsll(d, d, 16);
   3.388 +    set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
   3.389 +    count += 1;
   3.390 +    //ori(d, d, split_low(value));
   3.391 +    set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
   3.392 +    count += 1;
   3.393 +  } else {
   3.394 +    tty->print_cr("dest = 0x%x", value);
   3.395 +    guarantee(false, "Not supported yet !");
   3.396 +  }
   3.397 +
   3.398 +  for (count; count < 4; count++) {
   3.399 +    //nop();
   3.400 +    set_int_at(count << 2, 0);
   3.401 +  }
   3.402 +}
   3.403 +
   3.404  void  NativeCall::set_destination(address dest) {
   3.405  #ifndef _LP64
   3.406        OrderAccess::fence();
   3.407 @@ -204,10 +521,8 @@
   3.408        ICache::invalidate_range(addr_at(0), 8);
   3.409  #else
   3.410        OrderAccess::fence();
   3.411 -  /* 2013/6/13 Jin: ensure 100% atomicity */
   3.412 -  guarantee(!os::is_MP() || (((long)addr_at(0) % 16) == 0), "destination must be aligned for GSSD");
   3.413  
   3.414 -  /* li64 or li48 */
   3.415 +  // li64
   3.416    if (is_special_op(int_at(16), Assembler::dsll_op)) {
   3.417        int first_word = int_at(0);
   3.418        set_int_at(0, 0x1000ffff); /* .1: b .1 */
   3.419 @@ -218,23 +533,12 @@
   3.420        ICache::invalidate_range(addr_at(0), 24);
   3.421    } else if (is_special_op(int_at(16), Assembler::jalr_op)) {
   3.422      if (UseLoongsonISA) {
   3.423 -      int insts[4];
   3.424 -      insts[0] = (int_at(0) & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 32) & 0xffff);
   3.425 -      insts[1] = (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 16) & 0xffff);
   3.426 -      insts[2] = int_at(8);
   3.427 -      insts[3] = (int_at(12) & 0xffff0000) | (Assembler::split_low((intptr_t)dest) & 0xffff);
   3.428 -
   3.429 -      atomic_store128_ptr func = get_atomic_store128_func();
   3.430 -      (*func)((long *)addr_at(0), 0, *(long *)&insts[0], *(long *)&insts[2]);
   3.431 +      guarantee(!os::is_MP() || (((long)addr_at(0) % 16) == 0), "destination must be aligned for GSSD");
   3.432 +      patch_set48_gs(dest);
   3.433      } else {
   3.434 -      //assert(is_simm16(dest >> 32), "Not a 48-bit address");
   3.435 -      int first_word = int_at(0);
   3.436 -      set_int_at(0, 0x1000ffff); /* .1: b .1 */
   3.437 -      set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 16) & 0xffff));
   3.438 -      set_int_at(12, (int_at(12) & 0xffff0000) | (Assembler::split_low((intptr_t)dest) & 0xffff));
   3.439 -      set_int_at(0, (first_word & 0xffff0000) | (Assembler::split_low((intptr_t)dest >> 32) & 0xffff));
   3.440 -      ICache::invalidate_range(addr_at(0), 16);
   3.441 +      patch_set48(dest);
   3.442      }
   3.443 +    ICache::invalidate_range(addr_at(0), 16);
   3.444    } else {
   3.445        fatal("not a call");
   3.446    }
   3.447 @@ -256,7 +560,7 @@
   3.448    __ lui(T9, Assembler::split_high((int)entry));
   3.449    __ addiu(T9, T9, Assembler::split_low((int)entry));
   3.450  #else
   3.451 -  __ li48(T9, (long)entry);
   3.452 +  __ patchable_set48(T9, (long)entry);
   3.453  #endif
   3.454    __ jalr ();
   3.455    __ delayed()->nop();
   3.456 @@ -555,7 +859,7 @@
   3.457      set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
   3.458      count += 1;
   3.459    } else {
   3.460 -    tty->print_cr("In MacroAssembler::patchable_set48, value = 0x%x", value);
   3.461 +    tty->print_cr("value = 0x%x", value);
   3.462      guarantee(false, "Not supported yet !");
   3.463    }
   3.464  
     4.1 --- a/src/cpu/mips/vm/nativeInst_mips.hpp	Wed Mar 22 10:12:55 2017 +0800
     4.2 +++ b/src/cpu/mips/vm/nativeInst_mips.hpp	Sun Mar 05 13:20:40 2017 -0500
     4.3 @@ -174,6 +174,9 @@
     4.4      void  set_destination(address dest);
     4.5      void  set_destination_mt_safe(address dest) { set_destination(dest);}
     4.6  
     4.7 +    void  patch_set48_gs(address dest);
     4.8 +    void  patch_set48(address dest);
     4.9 +
    4.10      void  verify_alignment() {  }
    4.11      void  verify();
    4.12      void  print();

mercurial