1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2016 SAP SE. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #ifndef CPU_S390_VM_MACROASSEMBLER_S390_INLINE_HPP 27 #define CPU_S390_VM_MACROASSEMBLER_S390_INLINE_HPP 28 29 #include "asm/assembler.inline.hpp" 30 #include "asm/macroAssembler.hpp" 31 #include "asm/codeBuffer.hpp" 32 #include "code/codeCache.hpp" 33 #include "runtime/thread.hpp" 34 35 // Simplified shift operations for single register operands, constant shift amount. 36 inline void MacroAssembler::lshift(Register r, int places, bool is_DW) { 37 if (is_DW) { 38 z_sllg(r, r, places); 39 } else { 40 z_sll(r, places); 41 } 42 } 43 44 inline void MacroAssembler::rshift(Register r, int places, bool is_DW) { 45 if (is_DW) { 46 z_srlg(r, r, places); 47 } else { 48 z_srl(r, places); 49 } 50 } 51 52 // *((int8_t*)(dst)) |= imm8 53 inline void MacroAssembler::or2mem_8(Address& dst, int64_t imm8) { 54 if (Displacement::is_shortDisp(dst.disp())) { 55 z_oi(dst, imm8); 56 } else { 57 z_oiy(dst, imm8); 58 } 59 } 60 61 inline int MacroAssembler::store_const(const Address &dest, long imm, Register scratch, bool is_long) { 62 unsigned int lm = is_long ? 8 : 4; 63 unsigned int lc = is_long ? 8 : 4; 64 return store_const(dest, imm, lm, lc, scratch); 65 } 66 67 // Do not rely on add2reg* emitter. 68 // Depending on CmdLine switches and actual parameter values, 69 // the generated code may alter the condition code, which is counter-intuitive 70 // to the semantics of the "load address" (LA/LAY) instruction. 71 // Generic address loading d <- base(a) + index(a) + disp(a) 72 inline void MacroAssembler::load_address(Register d, const Address &a) { 73 if (Displacement::is_shortDisp(a.disp())) { 74 z_la(d, a.disp(), a.indexOrR0(), a.baseOrR0()); 75 } else if (Displacement::is_validDisp(a.disp())) { 76 z_lay(d, a.disp(), a.indexOrR0(), a.baseOrR0()); 77 } else { 78 guarantee(false, "displacement = " SIZE_FORMAT_HEX ", out of range for LA/LAY", a.disp()); 79 } 80 } 81 82 inline void MacroAssembler::load_const(Register t, void* x) { 83 load_const(t, (long)x); 84 } 85 86 // Load a 64 bit constant encoded by a `Label'. 87 // Works for bound as well as unbound labels. For unbound labels, the 88 // code will become patched as soon as the label gets bound. 89 inline void MacroAssembler::load_const(Register t, Label& L) { 90 load_const(t, target(L)); 91 } 92 93 inline void MacroAssembler::load_const(Register t, const AddressLiteral& a) { 94 assert(t != Z_R0, "R0 not allowed"); 95 // First relocate (we don't change the offset in the RelocationHolder, 96 // just pass a.rspec()), then delegate to load_const(Register, long). 97 relocate(a.rspec()); 98 load_const(t, (long)a.value()); 99 } 100 101 inline void MacroAssembler::load_const_optimized(Register t, long x) { 102 (void) load_const_optimized_rtn_len(t, x, true); 103 } 104 105 inline void MacroAssembler::load_const_optimized(Register t, void* a) { 106 load_const_optimized(t, (long)a); 107 } 108 109 inline void MacroAssembler::load_const_optimized(Register t, Label& L) { 110 load_const_optimized(t, target(L)); 111 } 112 113 inline void MacroAssembler::load_const_optimized(Register t, const AddressLiteral& a) { 114 assert(t != Z_R0, "R0 not allowed"); 115 assert((relocInfo::relocType)a.rspec().reloc()->type() == relocInfo::none, 116 "cannot relocate optimized load_consts"); 117 load_const_optimized(t, a.value()); 118 } 119 120 inline void MacroAssembler::set_oop(jobject obj, Register d) { 121 load_const(d, allocate_oop_address(obj)); 122 } 123 124 inline void MacroAssembler::set_oop_constant(jobject obj, Register d) { 125 load_const(d, constant_oop_address(obj)); 126 } 127 128 // Adds MetaData constant md to TOC and loads it from there. 129 // md is added to the oop_recorder, but no relocation is added. 130 inline bool MacroAssembler::set_metadata_constant(Metadata* md, Register d) { 131 AddressLiteral a = constant_metadata_address(md); 132 return load_const_from_toc(d, a, d); // Discards the relocation. 133 } 134 135 136 inline bool MacroAssembler::is_call_pcrelative_short(unsigned long inst) { 137 return is_equal(inst, BRAS_ZOPC); // off 16, len 16 138 } 139 140 inline bool MacroAssembler::is_call_pcrelative_long(unsigned long inst) { 141 return is_equal(inst, BRASL_ZOPC); // off 16, len 32 142 } 143 144 inline bool MacroAssembler::is_branch_pcrelative_short(unsigned long inst) { 145 // Branch relative, 16-bit offset. 146 return is_equal(inst, BRC_ZOPC); // off 16, len 16 147 } 148 149 inline bool MacroAssembler::is_branch_pcrelative_long(unsigned long inst) { 150 // Branch relative, 32-bit offset. 151 return is_equal(inst, BRCL_ZOPC); // off 16, len 32 152 } 153 154 inline bool MacroAssembler::is_compareandbranch_pcrelative_short(unsigned long inst) { 155 // Compare and branch relative, 16-bit offset. 156 return is_equal(inst, CRJ_ZOPC, CMPBRANCH_MASK) || is_equal(inst, CGRJ_ZOPC, CMPBRANCH_MASK) || 157 is_equal(inst, CIJ_ZOPC, CMPBRANCH_MASK) || is_equal(inst, CGIJ_ZOPC, CMPBRANCH_MASK) || 158 is_equal(inst, CLRJ_ZOPC, CMPBRANCH_MASK) || is_equal(inst, CLGRJ_ZOPC, CMPBRANCH_MASK) || 159 is_equal(inst, CLIJ_ZOPC, CMPBRANCH_MASK) || is_equal(inst, CLGIJ_ZOPC, CMPBRANCH_MASK); 160 } 161 162 inline bool MacroAssembler::is_branchoncount_pcrelative_short(unsigned long inst) { 163 // Branch relative on count, 16-bit offset. 164 return is_equal(inst, BRCT_ZOPC) || is_equal(inst, BRCTG_ZOPC); // off 16, len 16 165 } 166 167 inline bool MacroAssembler::is_branchonindex32_pcrelative_short(unsigned long inst) { 168 // Branch relative on index (32bit), 16-bit offset. 169 return is_equal(inst, BRXH_ZOPC) || is_equal(inst, BRXLE_ZOPC); // off 16, len 16 170 } 171 172 inline bool MacroAssembler::is_branchonindex64_pcrelative_short(unsigned long inst) { 173 // Branch relative on index (64bit), 16-bit offset. 174 return is_equal(inst, BRXHG_ZOPC) || is_equal(inst, BRXLG_ZOPC); // off 16, len 16 175 } 176 177 inline bool MacroAssembler::is_branchonindex_pcrelative_short(unsigned long inst) { 178 return is_branchonindex32_pcrelative_short(inst) || 179 is_branchonindex64_pcrelative_short(inst); 180 } 181 182 inline bool MacroAssembler::is_branch_pcrelative16(unsigned long inst) { 183 return is_branch_pcrelative_short(inst) || 184 is_compareandbranch_pcrelative_short(inst) || 185 is_branchoncount_pcrelative_short(inst) || 186 is_branchonindex_pcrelative_short(inst); 187 } 188 189 inline bool MacroAssembler::is_branch_pcrelative32(unsigned long inst) { 190 return is_branch_pcrelative_long(inst); 191 } 192 193 inline bool MacroAssembler::is_branch_pcrelative(unsigned long inst) { 194 return is_branch_pcrelative16(inst) || 195 is_branch_pcrelative32(inst); 196 } 197 198 inline bool MacroAssembler::is_load_pcrelative_long(unsigned long inst) { 199 // Load relative, 32-bit offset. 200 return is_equal(inst, LRL_ZOPC, REL_LONG_MASK) || is_equal(inst, LGRL_ZOPC, REL_LONG_MASK); // off 16, len 32 201 } 202 203 inline bool MacroAssembler::is_misc_pcrelative_long(unsigned long inst) { 204 // Load address, execute relative, 32-bit offset. 205 return is_equal(inst, LARL_ZOPC, REL_LONG_MASK) || is_equal(inst, EXRL_ZOPC, REL_LONG_MASK); // off 16, len 32 206 } 207 208 inline bool MacroAssembler::is_pcrelative_short(unsigned long inst) { 209 return is_branch_pcrelative16(inst) || 210 is_call_pcrelative_short(inst); 211 } 212 213 inline bool MacroAssembler::is_pcrelative_long(unsigned long inst) { 214 return is_branch_pcrelative32(inst) || 215 is_call_pcrelative_long(inst) || 216 is_load_pcrelative_long(inst) || 217 is_misc_pcrelative_long(inst); 218 } 219 220 inline bool MacroAssembler::is_load_pcrelative_long(address iLoc) { 221 unsigned long inst; 222 unsigned int len = get_instruction(iLoc, &inst); 223 return (len == 6) && is_load_pcrelative_long(inst); 224 } 225 226 inline bool MacroAssembler::is_pcrelative_short(address iLoc) { 227 unsigned long inst; 228 unsigned int len = get_instruction(iLoc, &inst); 229 return ((len == 4) || (len == 6)) && is_pcrelative_short(inst); 230 } 231 232 inline bool MacroAssembler::is_pcrelative_long(address iLoc) { 233 unsigned long inst; 234 unsigned int len = get_instruction(iLoc, &inst); 235 return (len == 6) && is_pcrelative_long(inst); 236 } 237 238 // Dynamic TOC. Test for any pc-relative instruction. 239 inline bool MacroAssembler::is_pcrelative_instruction(address iloc) { 240 unsigned long inst; 241 get_instruction(iloc, &inst); 242 return is_pcrelative_short(inst) || 243 is_pcrelative_long(inst); 244 } 245 246 inline bool MacroAssembler::is_load_addr_pcrel(address a) { 247 return is_equal(a, LARL_ZOPC, LARL_MASK); 248 } 249 250 // Save the return pc in the register that should be stored as the return pc 251 // in the current frame (default is R14). 252 inline void MacroAssembler::save_return_pc(Register pc) { 253 z_stg(pc, _z_abi16(return_pc), Z_SP); 254 } 255 256 inline void MacroAssembler::restore_return_pc() { 257 z_lg(Z_R14, _z_abi16(return_pc), Z_SP); 258 } 259 260 // Call a function with given entry. 261 inline address MacroAssembler::call(Register function_entry) { 262 assert(function_entry != Z_R0, "function_entry cannot be Z_R0"); 263 264 Assembler::z_basr(Z_R14, function_entry); 265 _last_calls_return_pc = pc(); 266 267 return _last_calls_return_pc; 268 } 269 270 // Call a C function via a function entry. 271 inline address MacroAssembler::call_c(Register function_entry) { 272 return call(function_entry); 273 } 274 275 // Call a stub function via a function descriptor, but don't save TOC before 276 // call, don't setup TOC and ENV for call, and don't restore TOC after call 277 inline address MacroAssembler::call_stub(Register function_entry) { 278 return call_c(function_entry); 279 } 280 281 inline address MacroAssembler::call_stub(address function_entry) { 282 return call_c(function_entry); 283 } 284 285 // Get the pc where the last emitted call will return to. 286 inline address MacroAssembler::last_calls_return_pc() { 287 return _last_calls_return_pc; 288 } 289 290 inline void MacroAssembler::set_last_Java_frame(Register last_Java_sp, Register last_Java_pc) { 291 set_last_Java_frame(last_Java_sp, last_Java_pc, true); 292 } 293 294 inline void MacroAssembler::set_last_Java_frame_static(Register last_Java_sp, Register last_Java_pc) { 295 set_last_Java_frame(last_Java_sp, last_Java_pc, false); 296 } 297 298 inline void MacroAssembler::reset_last_Java_frame(void) { 299 reset_last_Java_frame(true); 300 } 301 302 inline void MacroAssembler::reset_last_Java_frame_static(void) { 303 reset_last_Java_frame(false); 304 } 305 306 inline void MacroAssembler::set_top_ijava_frame_at_SP_as_last_Java_frame(Register sp, Register tmp1) { 307 set_top_ijava_frame_at_SP_as_last_Java_frame(sp, tmp1, true); 308 } 309 310 inline void MacroAssembler::set_top_ijava_frame_at_SP_as_last_Java_frame_static(Register sp, Register tmp1) { 311 set_top_ijava_frame_at_SP_as_last_Java_frame(sp, tmp1, true); 312 } 313 314 #endif // CPU_S390_VM_MACROASSEMBLER_S390_INLINE_HPP