1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/sparc/vm/assembler_sparc.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,1214 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef CPU_SPARC_VM_ASSEMBLER_SPARC_HPP 1.29 +#define CPU_SPARC_VM_ASSEMBLER_SPARC_HPP 1.30 + 1.31 +#include "asm/register.hpp" 1.32 + 1.33 +// The SPARC Assembler: Pure assembler doing NO optimizations on the instruction 1.34 +// level; i.e., what you write 1.35 +// is what you get. The Assembler is generating code into a CodeBuffer. 1.36 + 1.37 +class Assembler : public AbstractAssembler { 1.38 + friend class AbstractAssembler; 1.39 + friend class AddressLiteral; 1.40 + 1.41 + // code patchers need various routines like inv_wdisp() 1.42 + friend class NativeInstruction; 1.43 + friend class NativeGeneralJump; 1.44 + friend class Relocation; 1.45 + friend class Label; 1.46 + 1.47 + public: 1.48 + // op carries format info; see page 62 & 267 1.49 + 1.50 + enum ops { 1.51 + call_op = 1, // fmt 1 1.52 + branch_op = 0, // also sethi (fmt2) 1.53 + arith_op = 2, // fmt 3, arith & misc 1.54 + ldst_op = 3 // fmt 3, load/store 1.55 + }; 1.56 + 1.57 + enum op2s { 1.58 + bpr_op2 = 3, 1.59 + fb_op2 = 6, 1.60 + fbp_op2 = 5, 1.61 + br_op2 = 2, 1.62 + bp_op2 = 1, 1.63 + sethi_op2 = 4 1.64 + }; 1.65 + 1.66 + enum op3s { 1.67 + // selected op3s 1.68 + add_op3 = 0x00, 1.69 + and_op3 = 0x01, 1.70 + or_op3 = 0x02, 1.71 + xor_op3 = 0x03, 1.72 + sub_op3 = 0x04, 1.73 + andn_op3 = 0x05, 1.74 + orn_op3 = 0x06, 1.75 + xnor_op3 = 0x07, 1.76 + addc_op3 = 0x08, 1.77 + mulx_op3 = 0x09, 1.78 + umul_op3 = 0x0a, 1.79 + smul_op3 = 0x0b, 1.80 + subc_op3 = 0x0c, 1.81 + udivx_op3 = 0x0d, 1.82 + udiv_op3 = 0x0e, 1.83 + sdiv_op3 = 0x0f, 1.84 + 1.85 + addcc_op3 = 0x10, 1.86 + andcc_op3 = 0x11, 1.87 + orcc_op3 = 0x12, 1.88 + xorcc_op3 = 0x13, 1.89 + subcc_op3 = 0x14, 1.90 + andncc_op3 = 0x15, 1.91 + orncc_op3 = 0x16, 1.92 + xnorcc_op3 = 0x17, 1.93 + addccc_op3 = 0x18, 1.94 + aes4_op3 = 0x19, 1.95 + umulcc_op3 = 0x1a, 1.96 + smulcc_op3 = 0x1b, 1.97 + subccc_op3 = 0x1c, 1.98 + udivcc_op3 = 0x1e, 1.99 + sdivcc_op3 = 0x1f, 1.100 + 1.101 + taddcc_op3 = 0x20, 1.102 + tsubcc_op3 = 0x21, 1.103 + taddcctv_op3 = 0x22, 1.104 + tsubcctv_op3 = 0x23, 1.105 + mulscc_op3 = 0x24, 1.106 + sll_op3 = 0x25, 1.107 + sllx_op3 = 0x25, 1.108 + srl_op3 = 0x26, 1.109 + srlx_op3 = 0x26, 1.110 + sra_op3 = 0x27, 1.111 + srax_op3 = 0x27, 1.112 + rdreg_op3 = 0x28, 1.113 + membar_op3 = 0x28, 1.114 + 1.115 + flushw_op3 = 0x2b, 1.116 + movcc_op3 = 0x2c, 1.117 + sdivx_op3 = 0x2d, 1.118 + popc_op3 = 0x2e, 1.119 + movr_op3 = 0x2f, 1.120 + 1.121 + sir_op3 = 0x30, 1.122 + wrreg_op3 = 0x30, 1.123 + saved_op3 = 0x31, 1.124 + 1.125 + fpop1_op3 = 0x34, 1.126 + fpop2_op3 = 0x35, 1.127 + impdep1_op3 = 0x36, 1.128 + aes3_op3 = 0x36, 1.129 + alignaddr_op3 = 0x36, 1.130 + faligndata_op3 = 0x36, 1.131 + flog3_op3 = 0x36, 1.132 + edge_op3 = 0x36, 1.133 + fsrc_op3 = 0x36, 1.134 + impdep2_op3 = 0x37, 1.135 + stpartialf_op3 = 0x37, 1.136 + jmpl_op3 = 0x38, 1.137 + rett_op3 = 0x39, 1.138 + trap_op3 = 0x3a, 1.139 + flush_op3 = 0x3b, 1.140 + save_op3 = 0x3c, 1.141 + restore_op3 = 0x3d, 1.142 + done_op3 = 0x3e, 1.143 + retry_op3 = 0x3e, 1.144 + 1.145 + lduw_op3 = 0x00, 1.146 + ldub_op3 = 0x01, 1.147 + lduh_op3 = 0x02, 1.148 + ldd_op3 = 0x03, 1.149 + stw_op3 = 0x04, 1.150 + stb_op3 = 0x05, 1.151 + sth_op3 = 0x06, 1.152 + std_op3 = 0x07, 1.153 + ldsw_op3 = 0x08, 1.154 + ldsb_op3 = 0x09, 1.155 + ldsh_op3 = 0x0a, 1.156 + ldx_op3 = 0x0b, 1.157 + 1.158 + stx_op3 = 0x0e, 1.159 + swap_op3 = 0x0f, 1.160 + 1.161 + stwa_op3 = 0x14, 1.162 + stxa_op3 = 0x1e, 1.163 + 1.164 + ldf_op3 = 0x20, 1.165 + ldfsr_op3 = 0x21, 1.166 + ldqf_op3 = 0x22, 1.167 + lddf_op3 = 0x23, 1.168 + stf_op3 = 0x24, 1.169 + stfsr_op3 = 0x25, 1.170 + stqf_op3 = 0x26, 1.171 + stdf_op3 = 0x27, 1.172 + 1.173 + prefetch_op3 = 0x2d, 1.174 + 1.175 + casa_op3 = 0x3c, 1.176 + casxa_op3 = 0x3e, 1.177 + 1.178 + mftoi_op3 = 0x36, 1.179 + 1.180 + alt_bit_op3 = 0x10, 1.181 + cc_bit_op3 = 0x10 1.182 + }; 1.183 + 1.184 + enum opfs { 1.185 + // selected opfs 1.186 + edge8n_opf = 0x01, 1.187 + 1.188 + fmovs_opf = 0x01, 1.189 + fmovd_opf = 0x02, 1.190 + 1.191 + fnegs_opf = 0x05, 1.192 + fnegd_opf = 0x06, 1.193 + 1.194 + alignaddr_opf = 0x18, 1.195 + 1.196 + fadds_opf = 0x41, 1.197 + faddd_opf = 0x42, 1.198 + fsubs_opf = 0x45, 1.199 + fsubd_opf = 0x46, 1.200 + 1.201 + faligndata_opf = 0x48, 1.202 + 1.203 + fmuls_opf = 0x49, 1.204 + fmuld_opf = 0x4a, 1.205 + fdivs_opf = 0x4d, 1.206 + fdivd_opf = 0x4e, 1.207 + 1.208 + fcmps_opf = 0x51, 1.209 + fcmpd_opf = 0x52, 1.210 + 1.211 + fstox_opf = 0x81, 1.212 + fdtox_opf = 0x82, 1.213 + fxtos_opf = 0x84, 1.214 + fxtod_opf = 0x88, 1.215 + fitos_opf = 0xc4, 1.216 + fdtos_opf = 0xc6, 1.217 + fitod_opf = 0xc8, 1.218 + fstod_opf = 0xc9, 1.219 + fstoi_opf = 0xd1, 1.220 + fdtoi_opf = 0xd2, 1.221 + 1.222 + mdtox_opf = 0x110, 1.223 + mstouw_opf = 0x111, 1.224 + mstosw_opf = 0x113, 1.225 + mxtod_opf = 0x118, 1.226 + mwtos_opf = 0x119, 1.227 + 1.228 + aes_kexpand0_opf = 0x130, 1.229 + aes_kexpand2_opf = 0x131 1.230 + }; 1.231 + 1.232 + enum op5s { 1.233 + aes_eround01_op5 = 0x00, 1.234 + aes_eround23_op5 = 0x01, 1.235 + aes_dround01_op5 = 0x02, 1.236 + aes_dround23_op5 = 0x03, 1.237 + aes_eround01_l_op5 = 0x04, 1.238 + aes_eround23_l_op5 = 0x05, 1.239 + aes_dround01_l_op5 = 0x06, 1.240 + aes_dround23_l_op5 = 0x07, 1.241 + aes_kexpand1_op5 = 0x08 1.242 + }; 1.243 + 1.244 + enum RCondition { rc_z = 1, rc_lez = 2, rc_lz = 3, rc_nz = 5, rc_gz = 6, rc_gez = 7, rc_last = rc_gez }; 1.245 + 1.246 + enum Condition { 1.247 + // for FBfcc & FBPfcc instruction 1.248 + f_never = 0, 1.249 + f_notEqual = 1, 1.250 + f_notZero = 1, 1.251 + f_lessOrGreater = 2, 1.252 + f_unorderedOrLess = 3, 1.253 + f_less = 4, 1.254 + f_unorderedOrGreater = 5, 1.255 + f_greater = 6, 1.256 + f_unordered = 7, 1.257 + f_always = 8, 1.258 + f_equal = 9, 1.259 + f_zero = 9, 1.260 + f_unorderedOrEqual = 10, 1.261 + f_greaterOrEqual = 11, 1.262 + f_unorderedOrGreaterOrEqual = 12, 1.263 + f_lessOrEqual = 13, 1.264 + f_unorderedOrLessOrEqual = 14, 1.265 + f_ordered = 15, 1.266 + 1.267 + // V8 coproc, pp 123 v8 manual 1.268 + 1.269 + cp_always = 8, 1.270 + cp_never = 0, 1.271 + cp_3 = 7, 1.272 + cp_2 = 6, 1.273 + cp_2or3 = 5, 1.274 + cp_1 = 4, 1.275 + cp_1or3 = 3, 1.276 + cp_1or2 = 2, 1.277 + cp_1or2or3 = 1, 1.278 + cp_0 = 9, 1.279 + cp_0or3 = 10, 1.280 + cp_0or2 = 11, 1.281 + cp_0or2or3 = 12, 1.282 + cp_0or1 = 13, 1.283 + cp_0or1or3 = 14, 1.284 + cp_0or1or2 = 15, 1.285 + 1.286 + 1.287 + // for integers 1.288 + 1.289 + never = 0, 1.290 + equal = 1, 1.291 + zero = 1, 1.292 + lessEqual = 2, 1.293 + less = 3, 1.294 + lessEqualUnsigned = 4, 1.295 + lessUnsigned = 5, 1.296 + carrySet = 5, 1.297 + negative = 6, 1.298 + overflowSet = 7, 1.299 + always = 8, 1.300 + notEqual = 9, 1.301 + notZero = 9, 1.302 + greater = 10, 1.303 + greaterEqual = 11, 1.304 + greaterUnsigned = 12, 1.305 + greaterEqualUnsigned = 13, 1.306 + carryClear = 13, 1.307 + positive = 14, 1.308 + overflowClear = 15 1.309 + }; 1.310 + 1.311 + enum CC { 1.312 + icc = 0, xcc = 2, 1.313 + // ptr_cc is the correct condition code for a pointer or intptr_t: 1.314 + ptr_cc = NOT_LP64(icc) LP64_ONLY(xcc), 1.315 + fcc0 = 0, fcc1 = 1, fcc2 = 2, fcc3 = 3 1.316 + }; 1.317 + 1.318 + enum PrefetchFcn { 1.319 + severalReads = 0, oneRead = 1, severalWritesAndPossiblyReads = 2, oneWrite = 3, page = 4 1.320 + }; 1.321 + 1.322 + public: 1.323 + // Helper functions for groups of instructions 1.324 + 1.325 + enum Predict { pt = 1, pn = 0 }; // pt = predict taken 1.326 + 1.327 + enum Membar_mask_bits { // page 184, v9 1.328 + StoreStore = 1 << 3, 1.329 + LoadStore = 1 << 2, 1.330 + StoreLoad = 1 << 1, 1.331 + LoadLoad = 1 << 0, 1.332 + 1.333 + Sync = 1 << 6, 1.334 + MemIssue = 1 << 5, 1.335 + Lookaside = 1 << 4 1.336 + }; 1.337 + 1.338 + static bool is_in_wdisp_range(address a, address b, int nbits) { 1.339 + intptr_t d = intptr_t(b) - intptr_t(a); 1.340 + return is_simm(d, nbits + 2); 1.341 + } 1.342 + 1.343 + address target_distance(Label& L) { 1.344 + // Assembler::target(L) should be called only when 1.345 + // a branch instruction is emitted since non-bound 1.346 + // labels record current pc() as a branch address. 1.347 + if (L.is_bound()) return target(L); 1.348 + // Return current address for non-bound labels. 1.349 + return pc(); 1.350 + } 1.351 + 1.352 + // test if label is in simm16 range in words (wdisp16). 1.353 + bool is_in_wdisp16_range(Label& L) { 1.354 + return is_in_wdisp_range(target_distance(L), pc(), 16); 1.355 + } 1.356 + // test if the distance between two addresses fits in simm30 range in words 1.357 + static bool is_in_wdisp30_range(address a, address b) { 1.358 + return is_in_wdisp_range(a, b, 30); 1.359 + } 1.360 + 1.361 + enum ASIs { // page 72, v9 1.362 + ASI_PRIMARY = 0x80, 1.363 + ASI_PRIMARY_NOFAULT = 0x82, 1.364 + ASI_PRIMARY_LITTLE = 0x88, 1.365 + // 8x8-bit partial store 1.366 + ASI_PST8_PRIMARY = 0xC0, 1.367 + // Block initializing store 1.368 + ASI_ST_BLKINIT_PRIMARY = 0xE2, 1.369 + // Most-Recently-Used (MRU) BIS variant 1.370 + ASI_ST_BLKINIT_MRU_PRIMARY = 0xF2 1.371 + // add more from book as needed 1.372 + }; 1.373 + 1.374 + protected: 1.375 + // helpers 1.376 + 1.377 + // x is supposed to fit in a field "nbits" wide 1.378 + // and be sign-extended. Check the range. 1.379 + 1.380 + static void assert_signed_range(intptr_t x, int nbits) { 1.381 + assert(nbits == 32 || (-(1 << nbits-1) <= x && x < ( 1 << nbits-1)), 1.382 + err_msg("value out of range: x=" INTPTR_FORMAT ", nbits=%d", x, nbits)); 1.383 + } 1.384 + 1.385 + static void assert_signed_word_disp_range(intptr_t x, int nbits) { 1.386 + assert( (x & 3) == 0, "not word aligned"); 1.387 + assert_signed_range(x, nbits + 2); 1.388 + } 1.389 + 1.390 + static void assert_unsigned_const(int x, int nbits) { 1.391 + assert( juint(x) < juint(1 << nbits), "unsigned constant out of range"); 1.392 + } 1.393 + 1.394 + // fields: note bits numbered from LSB = 0, 1.395 + // fields known by inclusive bit range 1.396 + 1.397 + static int fmask(juint hi_bit, juint lo_bit) { 1.398 + assert( hi_bit >= lo_bit && 0 <= lo_bit && hi_bit < 32, "bad bits"); 1.399 + return (1 << ( hi_bit-lo_bit + 1 )) - 1; 1.400 + } 1.401 + 1.402 + // inverse of u_field 1.403 + 1.404 + static int inv_u_field(int x, int hi_bit, int lo_bit) { 1.405 + juint r = juint(x) >> lo_bit; 1.406 + r &= fmask( hi_bit, lo_bit); 1.407 + return int(r); 1.408 + } 1.409 + 1.410 + 1.411 + // signed version: extract from field and sign-extend 1.412 + 1.413 + static int inv_s_field(int x, int hi_bit, int lo_bit) { 1.414 + int sign_shift = 31 - hi_bit; 1.415 + return inv_u_field( ((x << sign_shift) >> sign_shift), hi_bit, lo_bit); 1.416 + } 1.417 + 1.418 + // given a field that ranges from hi_bit to lo_bit (inclusive, 1.419 + // LSB = 0), and an unsigned value for the field, 1.420 + // shift it into the field 1.421 + 1.422 +#ifdef ASSERT 1.423 + static int u_field(int x, int hi_bit, int lo_bit) { 1.424 + assert( ( x & ~fmask(hi_bit, lo_bit)) == 0, 1.425 + "value out of range"); 1.426 + int r = x << lo_bit; 1.427 + assert( inv_u_field(r, hi_bit, lo_bit) == x, "just checking"); 1.428 + return r; 1.429 + } 1.430 +#else 1.431 + // make sure this is inlined as it will reduce code size significantly 1.432 + #define u_field(x, hi_bit, lo_bit) ((x) << (lo_bit)) 1.433 +#endif 1.434 + 1.435 + static int inv_op( int x ) { return inv_u_field(x, 31, 30); } 1.436 + static int inv_op2( int x ) { return inv_u_field(x, 24, 22); } 1.437 + static int inv_op3( int x ) { return inv_u_field(x, 24, 19); } 1.438 + static int inv_cond( int x ){ return inv_u_field(x, 28, 25); } 1.439 + 1.440 + static bool inv_immed( int x ) { return (x & Assembler::immed(true)) != 0; } 1.441 + 1.442 + static Register inv_rd( int x ) { return as_Register(inv_u_field(x, 29, 25)); } 1.443 + static Register inv_rs1( int x ) { return as_Register(inv_u_field(x, 18, 14)); } 1.444 + static Register inv_rs2( int x ) { return as_Register(inv_u_field(x, 4, 0)); } 1.445 + 1.446 + static int op( int x) { return u_field(x, 31, 30); } 1.447 + static int rd( Register r) { return u_field(r->encoding(), 29, 25); } 1.448 + static int fcn( int x) { return u_field(x, 29, 25); } 1.449 + static int op3( int x) { return u_field(x, 24, 19); } 1.450 + static int rs1( Register r) { return u_field(r->encoding(), 18, 14); } 1.451 + static int rs2( Register r) { return u_field(r->encoding(), 4, 0); } 1.452 + static int annul( bool a) { return u_field(a ? 1 : 0, 29, 29); } 1.453 + static int cond( int x) { return u_field(x, 28, 25); } 1.454 + static int cond_mov( int x) { return u_field(x, 17, 14); } 1.455 + static int rcond( RCondition x) { return u_field(x, 12, 10); } 1.456 + static int op2( int x) { return u_field(x, 24, 22); } 1.457 + static int predict( bool p) { return u_field(p ? 1 : 0, 19, 19); } 1.458 + static int branchcc( CC fcca) { return u_field(fcca, 21, 20); } 1.459 + static int cmpcc( CC fcca) { return u_field(fcca, 26, 25); } 1.460 + static int imm_asi( int x) { return u_field(x, 12, 5); } 1.461 + static int immed( bool i) { return u_field(i ? 1 : 0, 13, 13); } 1.462 + static int opf_low6( int w) { return u_field(w, 10, 5); } 1.463 + static int opf_low5( int w) { return u_field(w, 9, 5); } 1.464 + static int op5( int x) { return u_field(x, 8, 5); } 1.465 + static int trapcc( CC cc) { return u_field(cc, 12, 11); } 1.466 + static int sx( int i) { return u_field(i, 12, 12); } // shift x=1 means 64-bit 1.467 + static int opf( int x) { return u_field(x, 13, 5); } 1.468 + 1.469 + static bool is_cbcond( int x ) { 1.470 + return (VM_Version::has_cbcond() && (inv_cond(x) > rc_last) && 1.471 + inv_op(x) == branch_op && inv_op2(x) == bpr_op2); 1.472 + } 1.473 + static bool is_cxb( int x ) { 1.474 + assert(is_cbcond(x), "wrong instruction"); 1.475 + return (x & (1<<21)) != 0; 1.476 + } 1.477 + static int cond_cbcond( int x) { return u_field((((x & 8)<<1) + 8 + (x & 7)), 29, 25); } 1.478 + static int inv_cond_cbcond(int x) { 1.479 + assert(is_cbcond(x), "wrong instruction"); 1.480 + return inv_u_field(x, 27, 25) | (inv_u_field(x, 29, 29)<<3); 1.481 + } 1.482 + 1.483 + static int opf_cc( CC c, bool useFloat ) { return u_field((useFloat ? 0 : 4) + c, 13, 11); } 1.484 + static int mov_cc( CC c, bool useFloat ) { return u_field(useFloat ? 0 : 1, 18, 18) | u_field(c, 12, 11); } 1.485 + 1.486 + static int fd( FloatRegister r, FloatRegisterImpl::Width fwa) { return u_field(r->encoding(fwa), 29, 25); }; 1.487 + static int fs1(FloatRegister r, FloatRegisterImpl::Width fwa) { return u_field(r->encoding(fwa), 18, 14); }; 1.488 + static int fs2(FloatRegister r, FloatRegisterImpl::Width fwa) { return u_field(r->encoding(fwa), 4, 0); }; 1.489 + static int fs3(FloatRegister r, FloatRegisterImpl::Width fwa) { return u_field(r->encoding(fwa), 13, 9); }; 1.490 + 1.491 + // some float instructions use this encoding on the op3 field 1.492 + static int alt_op3(int op, FloatRegisterImpl::Width w) { 1.493 + int r; 1.494 + switch(w) { 1.495 + case FloatRegisterImpl::S: r = op + 0; break; 1.496 + case FloatRegisterImpl::D: r = op + 3; break; 1.497 + case FloatRegisterImpl::Q: r = op + 2; break; 1.498 + default: ShouldNotReachHere(); break; 1.499 + } 1.500 + return op3(r); 1.501 + } 1.502 + 1.503 + 1.504 + // compute inverse of simm 1.505 + static int inv_simm(int x, int nbits) { 1.506 + return (int)(x << (32 - nbits)) >> (32 - nbits); 1.507 + } 1.508 + 1.509 + static int inv_simm13( int x ) { return inv_simm(x, 13); } 1.510 + 1.511 + // signed immediate, in low bits, nbits long 1.512 + static int simm(int x, int nbits) { 1.513 + assert_signed_range(x, nbits); 1.514 + return x & (( 1 << nbits ) - 1); 1.515 + } 1.516 + 1.517 + // compute inverse of wdisp16 1.518 + static intptr_t inv_wdisp16(int x, intptr_t pos) { 1.519 + int lo = x & (( 1 << 14 ) - 1); 1.520 + int hi = (x >> 20) & 3; 1.521 + if (hi >= 2) hi |= ~1; 1.522 + return (((hi << 14) | lo) << 2) + pos; 1.523 + } 1.524 + 1.525 + // word offset, 14 bits at LSend, 2 bits at B21, B20 1.526 + static int wdisp16(intptr_t x, intptr_t off) { 1.527 + intptr_t xx = x - off; 1.528 + assert_signed_word_disp_range(xx, 16); 1.529 + int r = (xx >> 2) & ((1 << 14) - 1) 1.530 + | ( ( (xx>>(2+14)) & 3 ) << 20 ); 1.531 + assert( inv_wdisp16(r, off) == x, "inverse is not inverse"); 1.532 + return r; 1.533 + } 1.534 + 1.535 + // compute inverse of wdisp10 1.536 + static intptr_t inv_wdisp10(int x, intptr_t pos) { 1.537 + assert(is_cbcond(x), "wrong instruction"); 1.538 + int lo = inv_u_field(x, 12, 5); 1.539 + int hi = (x >> 19) & 3; 1.540 + if (hi >= 2) hi |= ~1; 1.541 + return (((hi << 8) | lo) << 2) + pos; 1.542 + } 1.543 + 1.544 + // word offset for cbcond, 8 bits at [B12,B5], 2 bits at [B20,B19] 1.545 + static int wdisp10(intptr_t x, intptr_t off) { 1.546 + assert(VM_Version::has_cbcond(), "This CPU does not have CBCOND instruction"); 1.547 + intptr_t xx = x - off; 1.548 + assert_signed_word_disp_range(xx, 10); 1.549 + int r = ( ( (xx >> 2 ) & ((1 << 8) - 1) ) << 5 ) 1.550 + | ( ( (xx >> (2+8)) & 3 ) << 19 ); 1.551 + // Have to fake cbcond instruction to pass assert in inv_wdisp10() 1.552 + assert(inv_wdisp10((r | op(branch_op) | cond_cbcond(rc_last+1) | op2(bpr_op2)), off) == x, "inverse is not inverse"); 1.553 + return r; 1.554 + } 1.555 + 1.556 + // word displacement in low-order nbits bits 1.557 + 1.558 + static intptr_t inv_wdisp( int x, intptr_t pos, int nbits ) { 1.559 + int pre_sign_extend = x & (( 1 << nbits ) - 1); 1.560 + int r = pre_sign_extend >= ( 1 << (nbits-1) ) 1.561 + ? pre_sign_extend | ~(( 1 << nbits ) - 1) 1.562 + : pre_sign_extend; 1.563 + return (r << 2) + pos; 1.564 + } 1.565 + 1.566 + static int wdisp( intptr_t x, intptr_t off, int nbits ) { 1.567 + intptr_t xx = x - off; 1.568 + assert_signed_word_disp_range(xx, nbits); 1.569 + int r = (xx >> 2) & (( 1 << nbits ) - 1); 1.570 + assert( inv_wdisp( r, off, nbits ) == x, "inverse not inverse"); 1.571 + return r; 1.572 + } 1.573 + 1.574 + 1.575 + // Extract the top 32 bits in a 64 bit word 1.576 + static int32_t hi32( int64_t x ) { 1.577 + int32_t r = int32_t( (uint64_t)x >> 32 ); 1.578 + return r; 1.579 + } 1.580 + 1.581 + // given a sethi instruction, extract the constant, left-justified 1.582 + static int inv_hi22( int x ) { 1.583 + return x << 10; 1.584 + } 1.585 + 1.586 + // create an imm22 field, given a 32-bit left-justified constant 1.587 + static int hi22( int x ) { 1.588 + int r = int( juint(x) >> 10 ); 1.589 + assert( (r & ~((1 << 22) - 1)) == 0, "just checkin'"); 1.590 + return r; 1.591 + } 1.592 + 1.593 + // create a low10 __value__ (not a field) for a given a 32-bit constant 1.594 + static int low10( int x ) { 1.595 + return x & ((1 << 10) - 1); 1.596 + } 1.597 + 1.598 + // AES crypto instructions supported only on certain processors 1.599 + static void aes_only() { assert( VM_Version::has_aes(), "This instruction only works on SPARC with AES instructions support"); } 1.600 + 1.601 + // instruction only in VIS1 1.602 + static void vis1_only() { assert( VM_Version::has_vis1(), "This instruction only works on SPARC with VIS1"); } 1.603 + 1.604 + // instruction only in VIS2 1.605 + static void vis2_only() { assert( VM_Version::has_vis2(), "This instruction only works on SPARC with VIS2"); } 1.606 + 1.607 + // instruction only in VIS3 1.608 + static void vis3_only() { assert( VM_Version::has_vis3(), "This instruction only works on SPARC with VIS3"); } 1.609 + 1.610 + // instruction only in v9 1.611 + static void v9_only() { } // do nothing 1.612 + 1.613 + // instruction deprecated in v9 1.614 + static void v9_dep() { } // do nothing for now 1.615 + 1.616 + // v8 has no CC field 1.617 + static void v8_no_cc(CC cc) { if (cc) v9_only(); } 1.618 + 1.619 + protected: 1.620 + // Simple delay-slot scheme: 1.621 + // In order to check the programmer, the assembler keeps track of deley slots. 1.622 + // It forbids CTIs in delay slots (conservative, but should be OK). 1.623 + // Also, when putting an instruction into a delay slot, you must say 1.624 + // asm->delayed()->add(...), in order to check that you don't omit 1.625 + // delay-slot instructions. 1.626 + // To implement this, we use a simple FSA 1.627 + 1.628 +#ifdef ASSERT 1.629 + #define CHECK_DELAY 1.630 +#endif 1.631 +#ifdef CHECK_DELAY 1.632 + enum Delay_state { no_delay, at_delay_slot, filling_delay_slot } delay_state; 1.633 +#endif 1.634 + 1.635 + public: 1.636 + // Tells assembler next instruction must NOT be in delay slot. 1.637 + // Use at start of multinstruction macros. 1.638 + void assert_not_delayed() { 1.639 + // This is a separate overloading to avoid creation of string constants 1.640 + // in non-asserted code--with some compilers this pollutes the object code. 1.641 +#ifdef CHECK_DELAY 1.642 + assert_not_delayed("next instruction should not be a delay slot"); 1.643 +#endif 1.644 + } 1.645 + void assert_not_delayed(const char* msg) { 1.646 +#ifdef CHECK_DELAY 1.647 + assert(delay_state == no_delay, msg); 1.648 +#endif 1.649 + } 1.650 + 1.651 + protected: 1.652 + // Insert a nop if the previous is cbcond 1.653 + void insert_nop_after_cbcond() { 1.654 + if (UseCBCond && cbcond_before()) { 1.655 + nop(); 1.656 + } 1.657 + } 1.658 + // Delay slot helpers 1.659 + // cti is called when emitting control-transfer instruction, 1.660 + // BEFORE doing the emitting. 1.661 + // Only effective when assertion-checking is enabled. 1.662 + void cti() { 1.663 + // A cbcond instruction immediately followed by a CTI 1.664 + // instruction introduces pipeline stalls, we need to avoid that. 1.665 + no_cbcond_before(); 1.666 +#ifdef CHECK_DELAY 1.667 + assert_not_delayed("cti should not be in delay slot"); 1.668 +#endif 1.669 + } 1.670 + 1.671 + // called when emitting cti with a delay slot, AFTER emitting 1.672 + void has_delay_slot() { 1.673 +#ifdef CHECK_DELAY 1.674 + assert_not_delayed("just checking"); 1.675 + delay_state = at_delay_slot; 1.676 +#endif 1.677 + } 1.678 + 1.679 + // cbcond instruction should not be generated one after an other 1.680 + bool cbcond_before() { 1.681 + if (offset() == 0) return false; // it is first instruction 1.682 + int x = *(int*)(intptr_t(pc()) - 4); // previous instruction 1.683 + return is_cbcond(x); 1.684 + } 1.685 + 1.686 + void no_cbcond_before() { 1.687 + assert(offset() == 0 || !cbcond_before(), "cbcond should not follow an other cbcond"); 1.688 + } 1.689 +public: 1.690 + 1.691 + bool use_cbcond(Label& L) { 1.692 + if (!UseCBCond || cbcond_before()) return false; 1.693 + intptr_t x = intptr_t(target_distance(L)) - intptr_t(pc()); 1.694 + assert( (x & 3) == 0, "not word aligned"); 1.695 + return is_simm12(x); 1.696 + } 1.697 + 1.698 + // Tells assembler you know that next instruction is delayed 1.699 + Assembler* delayed() { 1.700 +#ifdef CHECK_DELAY 1.701 + assert ( delay_state == at_delay_slot, "delayed instruction is not in delay slot"); 1.702 + delay_state = filling_delay_slot; 1.703 +#endif 1.704 + return this; 1.705 + } 1.706 + 1.707 + void flush() { 1.708 +#ifdef CHECK_DELAY 1.709 + assert ( delay_state == no_delay, "ending code with a delay slot"); 1.710 +#endif 1.711 + AbstractAssembler::flush(); 1.712 + } 1.713 + 1.714 + inline void emit_int32(int); // shadows AbstractAssembler::emit_int32 1.715 + inline void emit_data(int x) { emit_int32(x); } 1.716 + inline void emit_data(int, RelocationHolder const&); 1.717 + inline void emit_data(int, relocInfo::relocType rtype); 1.718 + // helper for above fcns 1.719 + inline void check_delay(); 1.720 + 1.721 + 1.722 + public: 1.723 + // instructions, refer to page numbers in the SPARC Architecture Manual, V9 1.724 + 1.725 + // pp 135 (addc was addx in v8) 1.726 + 1.727 + inline void add(Register s1, Register s2, Register d ); 1.728 + inline void add(Register s1, int simm13a, Register d ); 1.729 + 1.730 + void addcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } 1.731 + void addcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(add_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.732 + void addc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | rs2(s2) ); } 1.733 + void addc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(addc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.734 + void addccc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } 1.735 + void addccc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(addc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.736 + 1.737 + 1.738 + // 4-operand AES instructions 1.739 + 1.740 + void aes_eround01( FloatRegister s1, FloatRegister s2, FloatRegister s3, FloatRegister d ) { aes_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes4_op3) | fs1(s1, FloatRegisterImpl::D) | fs3(s3, FloatRegisterImpl::D) | op5(aes_eround01_op5) | fs2(s2, FloatRegisterImpl::D) ); } 1.741 + void aes_eround23( FloatRegister s1, FloatRegister s2, FloatRegister s3, FloatRegister d ) { aes_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes4_op3) | fs1(s1, FloatRegisterImpl::D) | fs3(s3, FloatRegisterImpl::D) | op5(aes_eround23_op5) | fs2(s2, FloatRegisterImpl::D) ); } 1.742 + void aes_dround01( FloatRegister s1, FloatRegister s2, FloatRegister s3, FloatRegister d ) { aes_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes4_op3) | fs1(s1, FloatRegisterImpl::D) | fs3(s3, FloatRegisterImpl::D) | op5(aes_dround01_op5) | fs2(s2, FloatRegisterImpl::D) ); } 1.743 + void aes_dround23( FloatRegister s1, FloatRegister s2, FloatRegister s3, FloatRegister d ) { aes_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes4_op3) | fs1(s1, FloatRegisterImpl::D) | fs3(s3, FloatRegisterImpl::D) | op5(aes_dround23_op5) | fs2(s2, FloatRegisterImpl::D) ); } 1.744 + void aes_eround01_l( FloatRegister s1, FloatRegister s2, FloatRegister s3, FloatRegister d ) { aes_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes4_op3) | fs1(s1, FloatRegisterImpl::D) | fs3(s3, FloatRegisterImpl::D) | op5(aes_eround01_l_op5) | fs2(s2, FloatRegisterImpl::D) ); } 1.745 + void aes_eround23_l( FloatRegister s1, FloatRegister s2, FloatRegister s3, FloatRegister d ) { aes_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes4_op3) | fs1(s1, FloatRegisterImpl::D) | fs3(s3, FloatRegisterImpl::D) | op5(aes_eround23_l_op5) | fs2(s2, FloatRegisterImpl::D) ); } 1.746 + void aes_dround01_l( FloatRegister s1, FloatRegister s2, FloatRegister s3, FloatRegister d ) { aes_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes4_op3) | fs1(s1, FloatRegisterImpl::D) | fs3(s3, FloatRegisterImpl::D) | op5(aes_dround01_l_op5) | fs2(s2, FloatRegisterImpl::D) ); } 1.747 + void aes_dround23_l( FloatRegister s1, FloatRegister s2, FloatRegister s3, FloatRegister d ) { aes_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes4_op3) | fs1(s1, FloatRegisterImpl::D) | fs3(s3, FloatRegisterImpl::D) | op5(aes_dround23_l_op5) | fs2(s2, FloatRegisterImpl::D) ); } 1.748 + void aes_kexpand1( FloatRegister s1, FloatRegister s2, int imm5a, FloatRegister d ) { aes_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes4_op3) | fs1(s1, FloatRegisterImpl::D) | u_field(imm5a, 13, 9) | op5(aes_kexpand1_op5) | fs2(s2, FloatRegisterImpl::D) ); } 1.749 + 1.750 + 1.751 + // 3-operand AES instructions 1.752 + 1.753 + void aes_kexpand0( FloatRegister s1, FloatRegister s2, FloatRegister d ) { aes_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes3_op3) | fs1(s1, FloatRegisterImpl::D) | opf(aes_kexpand0_opf) | fs2(s2, FloatRegisterImpl::D) ); } 1.754 + void aes_kexpand2( FloatRegister s1, FloatRegister s2, FloatRegister d ) { aes_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(aes3_op3) | fs1(s1, FloatRegisterImpl::D) | opf(aes_kexpand2_opf) | fs2(s2, FloatRegisterImpl::D) ); } 1.755 + 1.756 + // pp 136 1.757 + 1.758 + inline void bpr(RCondition c, bool a, Predict p, Register s1, address d, relocInfo::relocType rt = relocInfo::none); 1.759 + inline void bpr(RCondition c, bool a, Predict p, Register s1, Label& L); 1.760 + 1.761 + // compare and branch 1.762 + inline void cbcond(Condition c, CC cc, Register s1, Register s2, Label& L); 1.763 + inline void cbcond(Condition c, CC cc, Register s1, int simm5, Label& L); 1.764 + 1.765 + protected: // use MacroAssembler::br instead 1.766 + 1.767 + // pp 138 1.768 + 1.769 + inline void fb( Condition c, bool a, address d, relocInfo::relocType rt = relocInfo::none ); 1.770 + inline void fb( Condition c, bool a, Label& L ); 1.771 + 1.772 + // pp 141 1.773 + 1.774 + inline void fbp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); 1.775 + inline void fbp( Condition c, bool a, CC cc, Predict p, Label& L ); 1.776 + 1.777 + // pp 144 1.778 + 1.779 + inline void br( Condition c, bool a, address d, relocInfo::relocType rt = relocInfo::none ); 1.780 + inline void br( Condition c, bool a, Label& L ); 1.781 + 1.782 + // pp 146 1.783 + 1.784 + inline void bp( Condition c, bool a, CC cc, Predict p, address d, relocInfo::relocType rt = relocInfo::none ); 1.785 + inline void bp( Condition c, bool a, CC cc, Predict p, Label& L ); 1.786 + 1.787 + // pp 149 1.788 + 1.789 + inline void call( address d, relocInfo::relocType rt = relocInfo::runtime_call_type ); 1.790 + inline void call( Label& L, relocInfo::relocType rt = relocInfo::runtime_call_type ); 1.791 + 1.792 + public: 1.793 + 1.794 + // pp 150 1.795 + 1.796 + // These instructions compare the contents of s2 with the contents of 1.797 + // memory at address in s1. If the values are equal, the contents of memory 1.798 + // at address s1 is swapped with the data in d. If the values are not equal, 1.799 + // the the contents of memory at s1 is loaded into d, without the swap. 1.800 + 1.801 + void casa( Register s1, Register s2, Register d, int ia = -1 ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(casa_op3 ) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); } 1.802 + void casxa( Register s1, Register s2, Register d, int ia = -1 ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(casxa_op3) | rs1(s1) | (ia == -1 ? immed(true) : imm_asi(ia)) | rs2(s2)); } 1.803 + 1.804 + // pp 152 1.805 + 1.806 + void udiv( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(udiv_op3 ) | rs1(s1) | rs2(s2)); } 1.807 + void udiv( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(udiv_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.808 + void sdiv( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sdiv_op3 ) | rs1(s1) | rs2(s2)); } 1.809 + void sdiv( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sdiv_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.810 + void udivcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(udiv_op3 | cc_bit_op3) | rs1(s1) | rs2(s2)); } 1.811 + void udivcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(udiv_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.812 + void sdivcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sdiv_op3 | cc_bit_op3) | rs1(s1) | rs2(s2)); } 1.813 + void sdivcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sdiv_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.814 + 1.815 + // pp 155 1.816 + 1.817 + void done() { v9_only(); cti(); emit_int32( op(arith_op) | fcn(0) | op3(done_op3) ); } 1.818 + void retry() { v9_only(); cti(); emit_int32( op(arith_op) | fcn(1) | op3(retry_op3) ); } 1.819 + 1.820 + // pp 156 1.821 + 1.822 + void fadd( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x40 + w) | fs2(s2, w)); } 1.823 + void fsub( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x44 + w) | fs2(s2, w)); } 1.824 + 1.825 + // pp 157 1.826 + 1.827 + void fcmp( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { emit_int32( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x50 + w) | fs2(s2, w)); } 1.828 + void fcmpe( FloatRegisterImpl::Width w, CC cc, FloatRegister s1, FloatRegister s2) { emit_int32( op(arith_op) | cmpcc(cc) | op3(fpop2_op3) | fs1(s1, w) | opf(0x54 + w) | fs2(s2, w)); } 1.829 + 1.830 + // pp 159 1.831 + 1.832 + void ftox( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(fpop1_op3) | opf(0x80 + w) | fs2(s, w)); } 1.833 + void ftoi( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(fpop1_op3) | opf(0xd0 + w) | fs2(s, w)); } 1.834 + 1.835 + // pp 160 1.836 + 1.837 + void ftof( FloatRegisterImpl::Width sw, FloatRegisterImpl::Width dw, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, dw) | op3(fpop1_op3) | opf(0xc0 + sw + dw*4) | fs2(s, sw)); } 1.838 + 1.839 + // pp 161 1.840 + 1.841 + void fxtof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { v9_only(); emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x80 + w*4) | fs2(s, FloatRegisterImpl::D)); } 1.842 + void fitof( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0xc0 + w*4) | fs2(s, FloatRegisterImpl::S)); } 1.843 + 1.844 + // pp 162 1.845 + 1.846 + void fmov( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x00 + w) | fs2(s, w)); } 1.847 + 1.848 + void fneg( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x04 + w) | fs2(s, w)); } 1.849 + 1.850 + void fabs( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x08 + w) | fs2(s, w)); } 1.851 + 1.852 + // pp 163 1.853 + 1.854 + void fmul( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x48 + w) | fs2(s2, w)); } 1.855 + void fmul( FloatRegisterImpl::Width sw, FloatRegisterImpl::Width dw, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, dw) | op3(fpop1_op3) | fs1(s1, sw) | opf(0x60 + sw + dw*4) | fs2(s2, sw)); } 1.856 + void fdiv( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | fs1(s1, w) | opf(0x4c + w) | fs2(s2, w)); } 1.857 + 1.858 + // FXORs/FXORd instructions 1.859 + 1.860 + void fxor( FloatRegisterImpl::Width w, FloatRegister s1, FloatRegister s2, FloatRegister d ) { vis1_only(); emit_int32( op(arith_op) | fd(d, w) | op3(flog3_op3) | fs1(s1, w) | opf(0x6E - w) | fs2(s2, w)); } 1.861 + 1.862 + // pp 164 1.863 + 1.864 + void fsqrt( FloatRegisterImpl::Width w, FloatRegister s, FloatRegister d ) { emit_int32( op(arith_op) | fd(d, w) | op3(fpop1_op3) | opf(0x28 + w) | fs2(s, w)); } 1.865 + 1.866 + // pp 165 1.867 + 1.868 + inline void flush( Register s1, Register s2 ); 1.869 + inline void flush( Register s1, int simm13a); 1.870 + 1.871 + // pp 167 1.872 + 1.873 + void flushw() { v9_only(); emit_int32( op(arith_op) | op3(flushw_op3) ); } 1.874 + 1.875 + // pp 168 1.876 + 1.877 + void illtrap( int const22a) { if (const22a != 0) v9_only(); emit_int32( op(branch_op) | u_field(const22a, 21, 0) ); } 1.878 + // v8 unimp == illtrap(0) 1.879 + 1.880 + // pp 169 1.881 + 1.882 + void impdep1( int id1, int const19a ) { v9_only(); emit_int32( op(arith_op) | fcn(id1) | op3(impdep1_op3) | u_field(const19a, 18, 0)); } 1.883 + void impdep2( int id1, int const19a ) { v9_only(); emit_int32( op(arith_op) | fcn(id1) | op3(impdep2_op3) | u_field(const19a, 18, 0)); } 1.884 + 1.885 + // pp 170 1.886 + 1.887 + void jmpl( Register s1, Register s2, Register d ); 1.888 + void jmpl( Register s1, int simm13a, Register d, RelocationHolder const& rspec = RelocationHolder() ); 1.889 + 1.890 + // 171 1.891 + 1.892 + inline void ldf(FloatRegisterImpl::Width w, Register s1, Register s2, FloatRegister d); 1.893 + inline void ldf(FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d, RelocationHolder const& rspec = RelocationHolder()); 1.894 + 1.895 + 1.896 + inline void ldfsr( Register s1, Register s2 ); 1.897 + inline void ldfsr( Register s1, int simm13a); 1.898 + inline void ldxfsr( Register s1, Register s2 ); 1.899 + inline void ldxfsr( Register s1, int simm13a); 1.900 + 1.901 + // 173 1.902 + 1.903 + void ldfa( FloatRegisterImpl::Width w, Register s1, Register s2, int ia, FloatRegister d ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.904 + void ldfa( FloatRegisterImpl::Width w, Register s1, int simm13a, FloatRegister d ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(ldf_op3 | alt_bit_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.905 + 1.906 + // pp 175, lduw is ld on v8 1.907 + 1.908 + inline void ldsb( Register s1, Register s2, Register d ); 1.909 + inline void ldsb( Register s1, int simm13a, Register d); 1.910 + inline void ldsh( Register s1, Register s2, Register d ); 1.911 + inline void ldsh( Register s1, int simm13a, Register d); 1.912 + inline void ldsw( Register s1, Register s2, Register d ); 1.913 + inline void ldsw( Register s1, int simm13a, Register d); 1.914 + inline void ldub( Register s1, Register s2, Register d ); 1.915 + inline void ldub( Register s1, int simm13a, Register d); 1.916 + inline void lduh( Register s1, Register s2, Register d ); 1.917 + inline void lduh( Register s1, int simm13a, Register d); 1.918 + inline void lduw( Register s1, Register s2, Register d ); 1.919 + inline void lduw( Register s1, int simm13a, Register d); 1.920 + inline void ldx( Register s1, Register s2, Register d ); 1.921 + inline void ldx( Register s1, int simm13a, Register d); 1.922 + inline void ldd( Register s1, Register s2, Register d ); 1.923 + inline void ldd( Register s1, int simm13a, Register d); 1.924 + 1.925 + // pp 177 1.926 + 1.927 + void ldsba( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.928 + void ldsba( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldsb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.929 + void ldsha( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.930 + void ldsha( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldsh_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.931 + void ldswa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldsw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.932 + void ldswa( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldsw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.933 + void lduba( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldub_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.934 + void lduba( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(ldub_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.935 + void lduha( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduh_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.936 + void lduha( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduh_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.937 + void lduwa( Register s1, Register s2, int ia, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.938 + void lduwa( Register s1, int simm13a, Register d ) { emit_int32( op(ldst_op) | rd(d) | op3(lduw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.939 + void ldxa( Register s1, Register s2, int ia, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.940 + void ldxa( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(ldx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.941 + 1.942 + // pp 181 1.943 + 1.944 + void and3( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(and_op3 ) | rs1(s1) | rs2(s2) ); } 1.945 + void and3( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(and_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.946 + void andcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(and_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } 1.947 + void andcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(and_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.948 + void andn( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(andn_op3 ) | rs1(s1) | rs2(s2) ); } 1.949 + void andn( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(andn_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.950 + void andncc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(andn_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } 1.951 + void andncc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(andn_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.952 + void or3( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(or_op3 ) | rs1(s1) | rs2(s2) ); } 1.953 + void or3( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(or_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.954 + void orcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(or_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } 1.955 + void orcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(or_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.956 + void orn( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(orn_op3) | rs1(s1) | rs2(s2) ); } 1.957 + void orn( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(orn_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.958 + void orncc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(orn_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } 1.959 + void orncc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(orn_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.960 + void xor3( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xor_op3 ) | rs1(s1) | rs2(s2) ); } 1.961 + void xor3( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xor_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.962 + void xorcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xor_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } 1.963 + void xorcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xor_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.964 + void xnor( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xnor_op3 ) | rs1(s1) | rs2(s2) ); } 1.965 + void xnor( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xnor_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.966 + void xnorcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xnor_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } 1.967 + void xnorcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(xnor_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.968 + 1.969 + // pp 183 1.970 + 1.971 + void membar( Membar_mask_bits const7a ) { v9_only(); emit_int32( op(arith_op) | op3(membar_op3) | rs1(O7) | immed(true) | u_field( int(const7a), 6, 0)); } 1.972 + 1.973 + // pp 185 1.974 + 1.975 + void fmov( FloatRegisterImpl::Width w, Condition c, bool floatCC, CC cca, FloatRegister s2, FloatRegister d ) { v9_only(); emit_int32( op(arith_op) | fd(d, w) | op3(fpop2_op3) | cond_mov(c) | opf_cc(cca, floatCC) | opf_low6(w) | fs2(s2, w)); } 1.976 + 1.977 + // pp 189 1.978 + 1.979 + void fmov( FloatRegisterImpl::Width w, RCondition c, Register s1, FloatRegister s2, FloatRegister d ) { v9_only(); emit_int32( op(arith_op) | fd(d, w) | op3(fpop2_op3) | rs1(s1) | rcond(c) | opf_low5(4 + w) | fs2(s2, w)); } 1.980 + 1.981 + // pp 191 1.982 + 1.983 + void movcc( Condition c, bool floatCC, CC cca, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(movcc_op3) | mov_cc(cca, floatCC) | cond_mov(c) | rs2(s2) ); } 1.984 + void movcc( Condition c, bool floatCC, CC cca, int simm11a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(movcc_op3) | mov_cc(cca, floatCC) | cond_mov(c) | immed(true) | simm(simm11a, 11) ); } 1.985 + 1.986 + // pp 195 1.987 + 1.988 + void movr( RCondition c, Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(movr_op3) | rs1(s1) | rcond(c) | rs2(s2) ); } 1.989 + void movr( RCondition c, Register s1, int simm10a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(movr_op3) | rs1(s1) | rcond(c) | immed(true) | simm(simm10a, 10) ); } 1.990 + 1.991 + // pp 196 1.992 + 1.993 + void mulx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(mulx_op3 ) | rs1(s1) | rs2(s2) ); } 1.994 + void mulx( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(mulx_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.995 + void sdivx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sdivx_op3) | rs1(s1) | rs2(s2) ); } 1.996 + void sdivx( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sdivx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.997 + void udivx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(udivx_op3) | rs1(s1) | rs2(s2) ); } 1.998 + void udivx( Register s1, int simm13a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(udivx_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.999 + 1.1000 + // pp 197 1.1001 + 1.1002 + void umul( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(umul_op3 ) | rs1(s1) | rs2(s2) ); } 1.1003 + void umul( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(umul_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1004 + void smul( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 ) | rs1(s1) | rs2(s2) ); } 1.1005 + void smul( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1006 + void umulcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(umul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } 1.1007 + void umulcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(umul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1008 + void smulcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } 1.1009 + void smulcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(smul_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1010 + 1.1011 + // pp 201 1.1012 + 1.1013 + void nop() { emit_int32( op(branch_op) | op2(sethi_op2) ); } 1.1014 + 1.1015 + 1.1016 + // pp 202 1.1017 + 1.1018 + void popc( Register s, Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(popc_op3) | rs2(s)); } 1.1019 + void popc( int simm13a, Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(popc_op3) | immed(true) | simm(simm13a, 13)); } 1.1020 + 1.1021 + // pp 203 1.1022 + 1.1023 + void prefetch( Register s1, Register s2, PrefetchFcn f) { v9_only(); emit_int32( op(ldst_op) | fcn(f) | op3(prefetch_op3) | rs1(s1) | rs2(s2) ); } 1.1024 + void prefetch( Register s1, int simm13a, PrefetchFcn f) { v9_only(); emit_data( op(ldst_op) | fcn(f) | op3(prefetch_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); } 1.1025 + 1.1026 + void prefetcha( Register s1, Register s2, int ia, PrefetchFcn f ) { v9_only(); emit_int32( op(ldst_op) | fcn(f) | op3(prefetch_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.1027 + void prefetcha( Register s1, int simm13a, PrefetchFcn f ) { v9_only(); emit_int32( op(ldst_op) | fcn(f) | op3(prefetch_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1028 + 1.1029 + // pp 208 1.1030 + 1.1031 + // not implementing read privileged register 1.1032 + 1.1033 + inline void rdy( Register d) { v9_dep(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(0, 18, 14)); } 1.1034 + inline void rdccr( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(2, 18, 14)); } 1.1035 + inline void rdasi( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(3, 18, 14)); } 1.1036 + inline void rdtick( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(4, 18, 14)); } // Spoon! 1.1037 + inline void rdpc( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(5, 18, 14)); } 1.1038 + inline void rdfprs( Register d) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(rdreg_op3) | u_field(6, 18, 14)); } 1.1039 + 1.1040 + // pp 213 1.1041 + 1.1042 + inline void rett( Register s1, Register s2); 1.1043 + inline void rett( Register s1, int simm13a, relocInfo::relocType rt = relocInfo::none); 1.1044 + 1.1045 + // pp 214 1.1046 + 1.1047 + void save( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | rs2(s2) ); } 1.1048 + void save( Register s1, int simm13a, Register d ) { 1.1049 + // make sure frame is at least large enough for the register save area 1.1050 + assert(-simm13a >= 16 * wordSize, "frame too small"); 1.1051 + emit_int32( op(arith_op) | rd(d) | op3(save_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); 1.1052 + } 1.1053 + 1.1054 + void restore( Register s1 = G0, Register s2 = G0, Register d = G0 ) { emit_int32( op(arith_op) | rd(d) | op3(restore_op3) | rs1(s1) | rs2(s2) ); } 1.1055 + void restore( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(restore_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1056 + 1.1057 + // pp 216 1.1058 + 1.1059 + void saved() { v9_only(); emit_int32( op(arith_op) | fcn(0) | op3(saved_op3)); } 1.1060 + void restored() { v9_only(); emit_int32( op(arith_op) | fcn(1) | op3(saved_op3)); } 1.1061 + 1.1062 + // pp 217 1.1063 + 1.1064 + inline void sethi( int imm22a, Register d, RelocationHolder const& rspec = RelocationHolder() ); 1.1065 + // pp 218 1.1066 + 1.1067 + void sll( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(0) | rs2(s2) ); } 1.1068 + void sll( Register s1, int imm5a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } 1.1069 + void srl( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(0) | rs2(s2) ); } 1.1070 + void srl( Register s1, int imm5a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } 1.1071 + void sra( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(0) | rs2(s2) ); } 1.1072 + void sra( Register s1, int imm5a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(0) | immed(true) | u_field(imm5a, 4, 0) ); } 1.1073 + 1.1074 + void sllx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(1) | rs2(s2) ); } 1.1075 + void sllx( Register s1, int imm6a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sll_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } 1.1076 + void srlx( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(1) | rs2(s2) ); } 1.1077 + void srlx( Register s1, int imm6a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(srl_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } 1.1078 + void srax( Register s1, Register s2, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(1) | rs2(s2) ); } 1.1079 + void srax( Register s1, int imm6a, Register d ) { v9_only(); emit_int32( op(arith_op) | rd(d) | op3(sra_op3) | rs1(s1) | sx(1) | immed(true) | u_field(imm6a, 5, 0) ); } 1.1080 + 1.1081 + // pp 220 1.1082 + 1.1083 + void sir( int simm13a ) { emit_int32( op(arith_op) | fcn(15) | op3(sir_op3) | immed(true) | simm(simm13a, 13)); } 1.1084 + 1.1085 + // pp 221 1.1086 + 1.1087 + void stbar() { emit_int32( op(arith_op) | op3(membar_op3) | u_field(15, 18, 14)); } 1.1088 + 1.1089 + // pp 222 1.1090 + 1.1091 + inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2); 1.1092 + inline void stf( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a); 1.1093 + 1.1094 + inline void stfsr( Register s1, Register s2 ); 1.1095 + inline void stfsr( Register s1, int simm13a); 1.1096 + inline void stxfsr( Register s1, Register s2 ); 1.1097 + inline void stxfsr( Register s1, int simm13a); 1.1098 + 1.1099 + // pp 224 1.1100 + 1.1101 + void stfa( FloatRegisterImpl::Width w, FloatRegister d, Register s1, Register s2, int ia ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(stf_op3 | alt_bit_op3, w) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.1102 + void stfa( FloatRegisterImpl::Width w, FloatRegister d, Register s1, int simm13a ) { v9_only(); emit_int32( op(ldst_op) | fd(d, w) | alt_op3(stf_op3 | alt_bit_op3, w) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1103 + 1.1104 + // p 226 1.1105 + 1.1106 + inline void stb( Register d, Register s1, Register s2 ); 1.1107 + inline void stb( Register d, Register s1, int simm13a); 1.1108 + inline void sth( Register d, Register s1, Register s2 ); 1.1109 + inline void sth( Register d, Register s1, int simm13a); 1.1110 + inline void stw( Register d, Register s1, Register s2 ); 1.1111 + inline void stw( Register d, Register s1, int simm13a); 1.1112 + inline void stx( Register d, Register s1, Register s2 ); 1.1113 + inline void stx( Register d, Register s1, int simm13a); 1.1114 + inline void std( Register d, Register s1, Register s2 ); 1.1115 + inline void std( Register d, Register s1, int simm13a); 1.1116 + 1.1117 + // pp 177 1.1118 + 1.1119 + void stba( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.1120 + void stba( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(stb_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1121 + void stha( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.1122 + void stha( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(sth_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1123 + void stwa( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(stw_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.1124 + void stwa( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(stw_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1125 + void stxa( Register d, Register s1, Register s2, int ia ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(stx_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.1126 + void stxa( Register d, Register s1, int simm13a ) { v9_only(); emit_int32( op(ldst_op) | rd(d) | op3(stx_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1127 + void stda( Register d, Register s1, Register s2, int ia ) { emit_int32( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.1128 + void stda( Register d, Register s1, int simm13a ) { emit_int32( op(ldst_op) | rd(d) | op3(std_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1129 + 1.1130 + // pp 230 1.1131 + 1.1132 + void sub( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | rs2(s2) ); } 1.1133 + void sub( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1134 + 1.1135 + void subcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | rs2(s2) ); } 1.1136 + void subcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(sub_op3 | cc_bit_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1137 + void subc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | rs2(s2) ); } 1.1138 + void subc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(subc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1139 + void subccc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(subc_op3 | cc_bit_op3) | rs1(s1) | rs2(s2) ); } 1.1140 + void subccc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(subc_op3 | cc_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1141 + 1.1142 + // pp 231 1.1143 + 1.1144 + inline void swap( Register s1, Register s2, Register d ); 1.1145 + inline void swap( Register s1, int simm13a, Register d); 1.1146 + 1.1147 + // pp 232 1.1148 + 1.1149 + void swapa( Register s1, Register s2, int ia, Register d ) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(swap_op3 | alt_bit_op3) | rs1(s1) | imm_asi(ia) | rs2(s2) ); } 1.1150 + void swapa( Register s1, int simm13a, Register d ) { v9_dep(); emit_int32( op(ldst_op) | rd(d) | op3(swap_op3 | alt_bit_op3) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1151 + 1.1152 + // pp 234, note op in book is wrong, see pp 268 1.1153 + 1.1154 + void taddcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | rs2(s2) ); } 1.1155 + void taddcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(taddcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1156 + 1.1157 + // pp 235 1.1158 + 1.1159 + void tsubcc( Register s1, Register s2, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | rs2(s2) ); } 1.1160 + void tsubcc( Register s1, int simm13a, Register d ) { emit_int32( op(arith_op) | rd(d) | op3(tsubcc_op3 ) | rs1(s1) | immed(true) | simm(simm13a, 13) ); } 1.1161 + 1.1162 + // pp 237 1.1163 + 1.1164 + void trap( Condition c, CC cc, Register s1, Register s2 ) { emit_int32( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | rs2(s2)); } 1.1165 + void trap( Condition c, CC cc, Register s1, int trapa ) { emit_int32( op(arith_op) | cond(c) | op3(trap_op3) | rs1(s1) | trapcc(cc) | immed(true) | u_field(trapa, 6, 0)); } 1.1166 + // simple uncond. trap 1.1167 + void trap( int trapa ) { trap( always, icc, G0, trapa ); } 1.1168 + 1.1169 + // pp 239 omit write priv register for now 1.1170 + 1.1171 + inline void wry( Register d) { v9_dep(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(0, 29, 25)); } 1.1172 + inline void wrccr(Register s) { v9_only(); emit_int32( op(arith_op) | rs1(s) | op3(wrreg_op3) | u_field(2, 29, 25)); } 1.1173 + inline void wrccr(Register s, int simm13a) { v9_only(); emit_int32( op(arith_op) | 1.1174 + rs1(s) | 1.1175 + op3(wrreg_op3) | 1.1176 + u_field(2, 29, 25) | 1.1177 + immed(true) | 1.1178 + simm(simm13a, 13)); } 1.1179 + inline void wrasi(Register d) { v9_only(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(3, 29, 25)); } 1.1180 + // wrasi(d, imm) stores (d xor imm) to asi 1.1181 + inline void wrasi(Register d, int simm13a) { v9_only(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | 1.1182 + u_field(3, 29, 25) | immed(true) | simm(simm13a, 13)); } 1.1183 + inline void wrfprs( Register d) { v9_only(); emit_int32( op(arith_op) | rs1(d) | op3(wrreg_op3) | u_field(6, 29, 25)); } 1.1184 + 1.1185 + 1.1186 + // VIS1 instructions 1.1187 + 1.1188 + void alignaddr( Register s1, Register s2, Register d ) { vis1_only(); emit_int32( op(arith_op) | rd(d) | op3(alignaddr_op3) | rs1(s1) | opf(alignaddr_opf) | rs2(s2)); } 1.1189 + 1.1190 + void faligndata( FloatRegister s1, FloatRegister s2, FloatRegister d ) { vis1_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(faligndata_op3) | fs1(s1, FloatRegisterImpl::D) | opf(faligndata_opf) | fs2(s2, FloatRegisterImpl::D)); } 1.1191 + 1.1192 + void fsrc2( FloatRegisterImpl::Width w, FloatRegister s2, FloatRegister d ) { vis1_only(); emit_int32( op(arith_op) | fd(d, w) | op3(fsrc_op3) | opf(0x7A - w) | fs2(s2, w)); } 1.1193 + 1.1194 + void stpartialf( Register s1, Register s2, FloatRegister d, int ia = -1 ) { vis1_only(); emit_int32( op(ldst_op) | fd(d, FloatRegisterImpl::D) | op3(stpartialf_op3) | rs1(s1) | imm_asi(ia) | rs2(s2)); } 1.1195 + 1.1196 + // VIS2 instructions 1.1197 + 1.1198 + void edge8n( Register s1, Register s2, Register d ) { vis2_only(); emit_int32( op(arith_op) | rd(d) | op3(edge_op3) | rs1(s1) | opf(edge8n_opf) | rs2(s2)); } 1.1199 + 1.1200 + // VIS3 instructions 1.1201 + 1.1202 + void movstosw( FloatRegister s, Register d ) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstosw_opf) | fs2(s, FloatRegisterImpl::S)); } 1.1203 + void movstouw( FloatRegister s, Register d ) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mstouw_opf) | fs2(s, FloatRegisterImpl::S)); } 1.1204 + void movdtox( FloatRegister s, Register d ) { vis3_only(); emit_int32( op(arith_op) | rd(d) | op3(mftoi_op3) | opf(mdtox_opf) | fs2(s, FloatRegisterImpl::D)); } 1.1205 + 1.1206 + void movwtos( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::S) | op3(mftoi_op3) | opf(mwtos_opf) | rs2(s)); } 1.1207 + void movxtod( Register s, FloatRegister d ) { vis3_only(); emit_int32( op(arith_op) | fd(d, FloatRegisterImpl::D) | op3(mftoi_op3) | opf(mxtod_opf) | rs2(s)); } 1.1208 + 1.1209 + // Creation 1.1210 + Assembler(CodeBuffer* code) : AbstractAssembler(code) { 1.1211 +#ifdef CHECK_DELAY 1.1212 + delay_state = no_delay; 1.1213 +#endif 1.1214 + } 1.1215 +}; 1.1216 + 1.1217 +#endif // CPU_SPARC_VM_ASSEMBLER_SPARC_HPP