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 }