/* * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2020 Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
void Assembler::emit_data64(jlong data,
RelocationHolder const& rspec, int format) {
assert(inst_mark() != NULL, "must be inside InstructionMark"); // Do not use AbstractAssembler::relocate, which is not intended for // embedded words. Instead, relocate to the enclosing instruction.
code_section()->relocate(inst_mark(), rspec, format);
emit_int64(data);
}
extern"C" { void das(uint64_t start, int len) {
ResourceMark rm;
len <<= 2; if (len < 0)
Disassembler::decode((address)start + len, (address)start); else
Disassembler::decode((address)start, (address)start + len);
}
// An "all-purpose" add/subtract immediate, per ARM documentation: // A "programmer-friendly" assembler may accept a negative immediate // between -(2^24 -1) and -1 inclusive, causing it to convert a // requested ADD operation to a SUB, or vice versa, and then encode // the absolute value of the immediate as for uimm24. void Assembler::add_sub_immediate(Instruction_aarch64 ¤t_insn, Register Rd, Register Rn, unsigned uimm, int op, int negated_op) { bool sets_flags = op & 1; // this op sets flags union { unsigned u; int imm;
};
u = uimm; bool shift = false; bool neg = imm < 0; if (neg) {
imm = -imm;
op = negated_op;
}
assert(Rd != sp || imm % 16 == 0, "misaligned stack"); if (imm >= (1 << 11)
&& ((imm >> 12) << 12 == imm)) {
imm >>= 12;
shift = true;
}
f(op, 31, 29), f(0b10001, 28, 24), f(shift, 23, 22), f(imm, 21, 10);
// add/subtract immediate ops with the S bit set treat r31 as zr; // with S unset they use sp. if (sets_flags)
zrf(Rd, 0); else
srf(Rd, 0);
srf(Rn, 5);
}
#undef f #undef sf #undef rf #undef srf #undef zrf #undef prf #undef pgrf #undef fixed
static RelocationHolder address_relocation(address target, relocInfo::relocType rtype) { switch (rtype) { case relocInfo::oop_type: case relocInfo::metadata_type: // Oops are a special case. Normally they would be their own section // but in cases like icBuffer they are literals in the code stream that // we don't have a section for. We use none so that we get a literal address // which is always patchable. return RelocationHolder::none; case relocInfo::external_word_type: return external_word_Relocation::spec(target); case relocInfo::internal_word_type: return internal_word_Relocation::spec(target); case relocInfo::opt_virtual_call_type: return opt_virtual_call_Relocation::spec(); case relocInfo::static_call_type: return static_call_Relocation::spec(); case relocInfo::runtime_call_type: return runtime_call_Relocation::spec(); case relocInfo::poll_type: case relocInfo::poll_return_type: return Relocation::spec_simple(rtype); case relocInfo::none: return RelocationHolder::none; default:
ShouldNotReachHere(); return RelocationHolder::none;
}
}
// Check immediate encoding for movi. // Return the shift amount which can be {0, 8, 16, 24} for B/H/S types. As the D type // movi does not have shift variant, in this case the return value is the immediate // after encoding. // Return -1 if the input imm64 can not be encoded. int Assembler::operand_valid_for_movi_immediate(uint64_t imm64, SIMD_Arrangement T) { if (T == T1D || T == T2D) { // To encode into movi, the 64-bit imm must be in the form of // 'aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhh' // and encoded in "a:b:c:d:e:f:g:h".
uint64_t tmp = imm64;
uint64_t one_byte = 0; for (int i = 0; i < 8; i++) {
one_byte = tmp & 0xffULL; if (one_byte != 0xffULL && one_byte != 0) { return -1; // can not be encoded
}
tmp = tmp >> 8;
}
bool Assembler::operand_valid_for_float_immediate(double imm) { // If imm is all zero bits we can use ZR as the source of a // floating-point value. if (doubleTo64Bits(imm) == 0) returntrue;
// Otherwise try to encode imm then convert the encoded value back // and make sure it's the exact same bit pattern. unsigned result = encoding_for_fp_immediate(imm); return doubleTo64Bits(imm) == fp_immediate_for_encoding(result, true);
}
int AbstractAssembler::code_fill_byte() { return 0;
}
// n.b. this is implemented in subclass MacroAssembler void Assembler::bang_stack_with_offset(int offset) { Unimplemented(); }
// and now the routines called by the assembler which encapsulate the // above encode and decode functions
uint32_t
asm_util::encode_logical_immediate(bool is32, uint64_t imm)
{ if (is32) { /* Allow all zeros or all ones in top 32-bits, so that
constant expressions like ~1 are permitted. */ if (imm >> 32 != 0 && imm >> 32 != 0xffffffff) return 0xffffffff; /* Replicate the 32 lower bits to the 32 upper bits. */
imm &= 0xffffffff;
imm |= imm << 32;
}
return encoding_for_logical_immediate(imm);
}
uint32_t
asm_util::encode_sve_logical_immediate(unsigned elembits, uint64_t imm) {
guarantee(elembits == 8 || elembits == 16 ||
elembits == 32 || elembits == 64, "unsupported element size");
uint64_t upper = UCONST64(-1) << (elembits/2) << (elembits/2); /* Allow all zeros or all ones in top bits, so that
* constant expressions like ~1 are permitted. */ if ((imm & ~upper) != imm && (imm | upper) != imm) return 0xffffffff;
// Replicate the immediate in different element sizes to 64 bits.
imm &= ~upper; for (unsigned i = elembits; i < 64; i *= 2) {
imm |= (imm << i);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.