1 /* 2 * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2014, 2020 Red Hat Inc. 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 #include <stdio.h> 26 #include <sys/types.h> 27 28 #include "precompiled.hpp" 29 #include "asm/assembler.hpp" 30 #include "asm/assembler.inline.hpp" 31 #include "interpreter/interpreter.hpp" 32 33 #ifndef PRODUCT 34 const uintptr_t Assembler::asm_bp = 0x00007fffee09ac88; 35 #endif 36 37 #include "compiler/disassembler.hpp" 38 #include "memory/resourceArea.hpp" 39 #include "runtime/interfaceSupport.inline.hpp" 40 #include "runtime/sharedRuntime.hpp" 41 #include "immediate_aarch64.hpp" 42 43 extern "C" void entry(CodeBuffer *cb); 44 45 #ifdef PRODUCT 46 #define BLOCK_COMMENT(str) /* nothing */ 47 #else 48 #define BLOCK_COMMENT(str) block_comment(str) 49 #endif 50 51 #define BIND(label) bind(label); __ BLOCK_COMMENT(#label ":") 52 53 static float unpack(unsigned value); 54 55 short Assembler::SIMD_Size_in_bytes[] = { 56 // T8B, T16B, T4H, T8H, T2S, T4S, T1D, T2D, T1Q 57 8, 16, 8, 16, 8, 16, 8, 16, 16 58 }; 59 60 void Assembler::emit_data64(jlong data, 61 relocInfo::relocType rtype, 62 int format) { 63 if (rtype == relocInfo::none) { 64 emit_int64(data); 65 } else { 66 emit_data64(data, Relocation::spec_simple(rtype), format); 67 } 68 } 69 70 void Assembler::emit_data64(jlong data, 71 RelocationHolder const& rspec, 72 int format) { 73 74 assert(inst_mark() != NULL, "must be inside InstructionMark"); 75 // Do not use AbstractAssembler::relocate, which is not intended for 76 // embedded words. Instead, relocate to the enclosing instruction. 77 code_section()->relocate(inst_mark(), rspec, format); 78 emit_int64(data); 79 } 80 81 extern "C" { 82 void das(uint64_t start, int len) { 83 ResourceMark rm; 84 len <<= 2; 85 if (len < 0) 86 Disassembler::decode((address)start + len, (address)start); 87 else 88 Disassembler::decode((address)start, (address)start + len); 89 } 90 91 JNIEXPORT void das1(uintptr_t insn) { 92 das(insn, 1); 93 } 94 } 95 96 #define gas_assert(ARG1) assert(ARG1, #ARG1) 97 98 #define __ as-> 99 100 void Address::lea(MacroAssembler *as, Register r) const { 101 Relocation* reloc = _rspec.reloc(); 102 relocInfo::relocType rtype = (relocInfo::relocType) reloc->type(); 103 104 switch(_mode) { 105 case base_plus_offset: { 106 if (_offset == 0 && _base == r) // it's a nop 107 break; 108 if (_offset > 0) 109 __ add(r, _base, _offset); 110 else 111 __ sub(r, _base, -_offset); 112 break; 113 } 114 case base_plus_offset_reg: { 115 __ add(r, _base, _index, _ext.op(), MAX2(_ext.shift(), 0)); 116 break; 117 } 118 case literal: { 119 if (rtype == relocInfo::none) 120 __ mov(r, target()); 121 else 122 __ movptr(r, (uint64_t)target()); 123 break; 124 } 125 default: 126 ShouldNotReachHere(); 127 } 128 } 129 130 void Assembler::adrp(Register reg1, const Address &dest, uintptr_t &byte_offset) { 131 ShouldNotReachHere(); 132 } 133 134 #undef __ 135 136 #define starti Instruction_aarch64 do_not_use(this); set_current(&do_not_use) 137 138 void Assembler::adr(Register Rd, address adr) { 139 intptr_t offset = adr - pc(); 140 int offset_lo = offset & 3; 141 offset >>= 2; 142 starti; 143 f(0, 31), f(offset_lo, 30, 29), f(0b10000, 28, 24), sf(offset, 23, 5); 144 rf(Rd, 0); 145 } 146 147 void Assembler::_adrp(Register Rd, address adr) { 148 uint64_t pc_page = (uint64_t)pc() >> 12; 149 uint64_t adr_page = (uint64_t)adr >> 12; 150 intptr_t offset = adr_page - pc_page; 151 int offset_lo = offset & 3; 152 offset >>= 2; 153 starti; 154 f(1, 31), f(offset_lo, 30, 29), f(0b10000, 28, 24), sf(offset, 23, 5); 155 rf(Rd, 0); 156 } 157 158 #undef starti 159 160 Address::Address(address target, relocInfo::relocType rtype) : _mode(literal){ 161 _is_lval = false; 162 _target = target; 163 switch (rtype) { 164 case relocInfo::oop_type: 165 case relocInfo::metadata_type: 166 // Oops are a special case. Normally they would be their own section 167 // but in cases like icBuffer they are literals in the code stream that 168 // we don't have a section for. We use none so that we get a literal address 169 // which is always patchable. 170 break; 171 case relocInfo::external_word_type: 172 _rspec = external_word_Relocation::spec(target); 173 break; 174 case relocInfo::internal_word_type: 175 _rspec = internal_word_Relocation::spec(target); 176 break; 177 case relocInfo::opt_virtual_call_type: 178 _rspec = opt_virtual_call_Relocation::spec(); 179 break; 180 case relocInfo::static_call_type: 181 _rspec = static_call_Relocation::spec(); 182 break; 183 case relocInfo::runtime_call_type: 184 _rspec = runtime_call_Relocation::spec(); 185 break; 186 case relocInfo::poll_type: 187 case relocInfo::poll_return_type: 188 _rspec = Relocation::spec_simple(rtype); 189 break; 190 case relocInfo::none: 191 _rspec = RelocationHolder::none; 192 break; 193 default: 194 ShouldNotReachHere(); 195 break; 196 } 197 } 198 199 void Assembler::b(const Address &dest) { 200 code_section()->relocate(pc(), dest.rspec()); 201 b(dest.target()); 202 } 203 204 void Assembler::bl(const Address &dest) { 205 code_section()->relocate(pc(), dest.rspec()); 206 bl(dest.target()); 207 } 208 209 void Assembler::adr(Register r, const Address &dest) { 210 code_section()->relocate(pc(), dest.rspec()); 211 adr(r, dest.target()); 212 } 213 214 void Assembler::br(Condition cc, Label &L) { 215 if (L.is_bound()) { 216 br(cc, target(L)); 217 } else { 218 L.add_patch_at(code(), locator()); 219 br(cc, pc()); 220 } 221 } 222 223 void Assembler::wrap_label(Label &L, 224 Assembler::uncond_branch_insn insn) { 225 if (L.is_bound()) { 226 (this->*insn)(target(L)); 227 } else { 228 L.add_patch_at(code(), locator()); 229 (this->*insn)(pc()); 230 } 231 } 232 233 void Assembler::wrap_label(Register r, Label &L, 234 compare_and_branch_insn insn) { 235 if (L.is_bound()) { 236 (this->*insn)(r, target(L)); 237 } else { 238 L.add_patch_at(code(), locator()); 239 (this->*insn)(r, pc()); 240 } 241 } 242 243 void Assembler::wrap_label(Register r, int bitpos, Label &L, 244 test_and_branch_insn insn) { 245 if (L.is_bound()) { 246 (this->*insn)(r, bitpos, target(L)); 247 } else { 248 L.add_patch_at(code(), locator()); 249 (this->*insn)(r, bitpos, pc()); 250 } 251 } 252 253 void Assembler::wrap_label(Label &L, prfop op, prefetch_insn insn) { 254 if (L.is_bound()) { 255 (this->*insn)(target(L), op); 256 } else { 257 L.add_patch_at(code(), locator()); 258 (this->*insn)(pc(), op); 259 } 260 } 261 262 // An "all-purpose" add/subtract immediate, per ARM documentation: 263 // A "programmer-friendly" assembler may accept a negative immediate 264 // between -(2^24 -1) and -1 inclusive, causing it to convert a 265 // requested ADD operation to a SUB, or vice versa, and then encode 266 // the absolute value of the immediate as for uimm24. 267 void Assembler::add_sub_immediate(Register Rd, Register Rn, unsigned uimm, int op, 268 int negated_op) { 269 bool sets_flags = op & 1; // this op sets flags 270 union { 271 unsigned u; 272 int imm; 273 }; 274 u = uimm; 275 bool shift = false; 276 bool neg = imm < 0; 277 if (neg) { 278 imm = -imm; 279 op = negated_op; 280 } 281 assert(Rd != sp || imm % 16 == 0, "misaligned stack"); 282 if (imm >= (1 << 11) 283 && ((imm >> 12) << 12 == imm)) { 284 imm >>= 12; 285 shift = true; 286 } 287 f(op, 31, 29), f(0b10001, 28, 24), f(shift, 23, 22), f(imm, 21, 10); 288 289 // add/subtract immediate ops with the S bit set treat r31 as zr; 290 // with S unset they use sp. 291 if (sets_flags) 292 zrf(Rd, 0); 293 else 294 srf(Rd, 0); 295 296 srf(Rn, 5); 297 } 298 299 bool Assembler::operand_valid_for_add_sub_immediate(int64_t imm) { 300 bool shift = false; 301 uint64_t uimm = (uint64_t)uabs(imm); 302 if (uimm < (1 << 12)) 303 return true; 304 if (uimm < (1 << 24) 305 && ((uimm >> 12) << 12 == uimm)) { 306 return true; 307 } 308 return false; 309 } 310 311 bool Assembler::operand_valid_for_logical_immediate(bool is32, uint64_t imm) { 312 return encode_logical_immediate(is32, imm) != 0xffffffff; 313 } 314 315 static uint64_t doubleTo64Bits(jdouble d) { 316 union { 317 jdouble double_value; 318 uint64_t double_bits; 319 }; 320 321 double_value = d; 322 return double_bits; 323 } 324 325 bool Assembler::operand_valid_for_float_immediate(double imm) { 326 // If imm is all zero bits we can use ZR as the source of a 327 // floating-point value. 328 if (doubleTo64Bits(imm) == 0) 329 return true; 330 331 // Otherwise try to encode imm then convert the encoded value back 332 // and make sure it's the exact same bit pattern. 333 unsigned result = encoding_for_fp_immediate(imm); 334 return doubleTo64Bits(imm) == fp_immediate_for_encoding(result, true); 335 } 336 337 int AbstractAssembler::code_fill_byte() { 338 return 0; 339 } 340 341 // n.b. this is implemented in subclass MacroAssembler 342 void Assembler::bang_stack_with_offset(int offset) { Unimplemented(); } 343 344 345 // and now the routines called by the assembler which encapsulate the 346 // above encode and decode functions 347 348 uint32_t 349 asm_util::encode_logical_immediate(bool is32, uint64_t imm) 350 { 351 if (is32) { 352 /* Allow all zeros or all ones in top 32-bits, so that 353 constant expressions like ~1 are permitted. */ 354 if (imm >> 32 != 0 && imm >> 32 != 0xffffffff) 355 return 0xffffffff; 356 /* Replicate the 32 lower bits to the 32 upper bits. */ 357 imm &= 0xffffffff; 358 imm |= imm << 32; 359 } 360 361 return encoding_for_logical_immediate(imm); 362 } 363 364 unsigned Assembler::pack(double value) { 365 float val = (float)value; 366 unsigned result = encoding_for_fp_immediate(val); 367 guarantee(unpack(result) == value, 368 "Invalid floating-point immediate operand"); 369 return result; 370 } 371 372 // Packed operands for Floating-point Move (immediate) 373 374 static float unpack(unsigned value) { 375 union { 376 unsigned ival; 377 float val; 378 }; 379 ival = fp_immediate_for_encoding(value, 0); 380 return val; 381 }