< prev index next >
src/hotspot/cpu/aarch64/assembler_aarch64.hpp
Print this page
8248238: Adding Windows support to OpenJDK on AArch64
Summary: LP64 vs LLP64 changes to add Windows support
Contributed-by: Monica Beckwith <monica.beckwith@microsoft.com>, Ludovic Henry <luhenry@microsoft.com>
Reviewed-by:
*** 197,207 ****
static inline int32_t sextract(uint32_t val, int msb, int lsb) {
uint32_t uval = extract(val, msb, lsb);
return extend(uval, msb - lsb);
}
! static void patch(address a, int msb, int lsb, unsigned long val) {
int nbits = msb - lsb + 1;
guarantee(val < (1U << nbits), "Field too big for insn");
assert_cond(msb >= lsb);
unsigned mask = (1U << nbits) - 1;
val <<= lsb;
--- 197,207 ----
static inline int32_t sextract(uint32_t val, int msb, int lsb) {
uint32_t uval = extract(val, msb, lsb);
return extend(uval, msb - lsb);
}
! static void patch(address a, int msb, int lsb, uint64_t val) {
int nbits = msb - lsb + 1;
guarantee(val < (1U << nbits), "Field too big for insn");
assert_cond(msb >= lsb);
unsigned mask = (1U << nbits) - 1;
val <<= lsb;
*** 210,222 ****
target &= ~mask;
target |= val;
*(unsigned *)a = target;
}
! static void spatch(address a, int msb, int lsb, long val) {
int nbits = msb - lsb + 1;
! long chk = val >> (nbits - 1);
guarantee (chk == -1 || chk == 0, "Field too big for insn");
unsigned uval = val;
unsigned mask = (1U << nbits) - 1;
uval &= mask;
uval <<= lsb;
--- 210,222 ----
target &= ~mask;
target |= val;
*(unsigned *)a = target;
}
! static void spatch(address a, int msb, int lsb, int64_t val) {
int nbits = msb - lsb + 1;
! int64_t chk = val >> (nbits - 1);
guarantee (chk == -1 || chk == 0, "Field too big for insn");
unsigned uval = val;
unsigned mask = (1U << nbits) - 1;
uval &= mask;
uval <<= lsb;
*** 243,255 ****
void f(unsigned val, int bit) {
f(val, bit, bit);
}
! void sf(long val, int msb, int lsb) {
int nbits = msb - lsb + 1;
! long chk = val >> (nbits - 1);
guarantee (chk == -1 || chk == 0, "Field too big for insn");
unsigned uval = val;
unsigned mask = (1U << nbits) - 1;
uval &= mask;
f(uval, lsb + nbits - 1, lsb);
--- 243,255 ----
void f(unsigned val, int bit) {
f(val, bit, bit);
}
! void sf(int64_t val, int msb, int lsb) {
int nbits = msb - lsb + 1;
! int64_t chk = val >> (nbits - 1);
guarantee (chk == -1 || chk == 0, "Field too big for insn");
unsigned uval = val;
unsigned mask = (1U << nbits) - 1;
uval &= mask;
f(uval, lsb + nbits - 1, lsb);
*** 355,365 ****
};
private:
Register _base;
Register _index;
! long _offset;
enum mode _mode;
extend _ext;
RelocationHolder _rspec;
--- 355,365 ----
};
private:
Register _base;
Register _index;
! int64_t _offset;
enum mode _mode;
extend _ext;
RelocationHolder _rspec;
*** 378,390 ****
: _mode(no_mode) { }
Address(Register r)
: _base(r), _index(noreg), _offset(0), _mode(base_plus_offset), _target(0) { }
Address(Register r, int o)
: _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { }
! Address(Register r, long o)
: _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { }
! Address(Register r, unsigned long o)
: _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { }
#ifdef ASSERT
Address(Register r, ByteSize disp)
: _base(r), _index(noreg), _offset(in_bytes(disp)), _mode(base_plus_offset), _target(0) { }
#endif
--- 378,390 ----
: _mode(no_mode) { }
Address(Register r)
: _base(r), _index(noreg), _offset(0), _mode(base_plus_offset), _target(0) { }
Address(Register r, int o)
: _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { }
! Address(Register r, int64_t o)
: _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { }
! Address(Register r, uint64_t o)
: _base(r), _index(noreg), _offset(o), _mode(base_plus_offset), _target(0) { }
#ifdef ASSERT
Address(Register r, ByteSize disp)
: _base(r), _index(noreg), _offset(in_bytes(disp)), _mode(base_plus_offset), _target(0) { }
#endif
*** 420,430 ****
guarantee((_mode == base_plus_offset | _mode == base_plus_offset_reg
| _mode == post | _mode == post_reg),
"wrong mode");
return _base;
}
! long offset() const {
return _offset;
}
Register index() const {
return _index;
}
--- 420,430 ----
guarantee((_mode == base_plus_offset | _mode == base_plus_offset_reg
| _mode == post | _mode == post_reg),
"wrong mode");
return _base;
}
! int64_t offset() const {
return _offset;
}
Register index() const {
return _index;
}
*** 552,562 ****
"Bad addressing mode for non-temporal op");
}
void lea(MacroAssembler *, Register) const;
! static bool offset_ok_for_immed(long offset, int shift) {
unsigned mask = (1 << shift) - 1;
if (offset < 0 || offset & mask) {
return (uabs(offset) < (1 << (20 - 12))); // Unscaled offset
} else {
return ((offset >> shift) < (1 << (21 - 10 + 1))); // Scaled, unsigned offset
--- 552,562 ----
"Bad addressing mode for non-temporal op");
}
void lea(MacroAssembler *, Register) const;
! static bool offset_ok_for_immed(int64_t offset, int shift) {
unsigned mask = (1 << shift) - 1;
if (offset < 0 || offset & mask) {
return (uabs(offset) < (1 << (20 - 12))); // Unscaled offset
} else {
return ((offset >> shift) < (1 << (21 - 10 + 1))); // Scaled, unsigned offset
*** 614,627 ****
} prfop;
class Assembler : public AbstractAssembler {
#ifndef PRODUCT
! static const unsigned long asm_bp;
void emit_long(jint x) {
! if ((unsigned long)pc() == asm_bp)
asm volatile ("nop");
AbstractAssembler::emit_int32(x);
}
#else
void emit_long(jint x) {
--- 614,627 ----
} prfop;
class Assembler : public AbstractAssembler {
#ifndef PRODUCT
! static const uint64_t asm_bp;
void emit_long(jint x) {
! if ((uint64_t)pc() == asm_bp)
asm volatile ("nop");
AbstractAssembler::emit_int32(x);
}
#else
void emit_long(jint x) {
*** 668,678 ****
current->f(val, msb, lsb);
}
void f(unsigned val, int msb) {
current->f(val, msb, msb);
}
! void sf(long val, int msb, int lsb) {
current->sf(val, msb, lsb);
}
void rf(Register reg, int lsb) {
current->rf(reg, lsb);
}
--- 668,678 ----
current->f(val, msb, lsb);
}
void f(unsigned val, int msb) {
current->f(val, msb, msb);
}
! void sf(int64_t val, int msb, int lsb) {
current->sf(val, msb, lsb);
}
void rf(Register reg, int lsb) {
current->rf(reg, lsb);
}
*** 718,728 ****
}
void _adrp(Register Rd, Label &L) {
wrap_label(Rd, L, &Assembler::_adrp);
}
! void adrp(Register Rd, const Address &dest, unsigned long &offset);
#undef INSN
void add_sub_immediate(Register Rd, Register Rn, unsigned uimm, int op,
int negated_op);
--- 718,728 ----
}
void _adrp(Register Rd, Label &L) {
wrap_label(Rd, L, &Assembler::_adrp);
}
! void adrp(Register Rd, const Address &dest, uint64_t &offset);
#undef INSN
void add_sub_immediate(Register Rd, Register Rn, unsigned uimm, int op,
int negated_op);
*** 844,864 ****
// The maximum range of a branch is fixed for the AArch64
// architecture. In debug mode we shrink it in order to test
// trampolines, but not so small that branches in the interpreter
// are out of range.
! static const unsigned long branch_range = NOT_DEBUG(128 * M) DEBUG_ONLY(2 * M);
static bool reachable_from_branch_at(address branch, address target) {
return uabs(target - branch) < branch_range;
}
// Unconditional branch (immediate)
#define INSN(NAME, opcode) \
void NAME(address dest) { \
starti; \
! long offset = (dest - pc()) >> 2; \
DEBUG_ONLY(assert(reachable_from_branch_at(pc(), dest), "debug only")); \
f(opcode, 31), f(0b00101, 30, 26), sf(offset, 25, 0); \
} \
void NAME(Label &L) { \
wrap_label(L, &Assembler::NAME); \
--- 844,864 ----
// The maximum range of a branch is fixed for the AArch64
// architecture. In debug mode we shrink it in order to test
// trampolines, but not so small that branches in the interpreter
// are out of range.
! static const uint64_t branch_range = NOT_DEBUG(128 * M) DEBUG_ONLY(2 * M);
static bool reachable_from_branch_at(address branch, address target) {
return uabs(target - branch) < branch_range;
}
// Unconditional branch (immediate)
#define INSN(NAME, opcode) \
void NAME(address dest) { \
starti; \
! int64_t offset = (dest - pc()) >> 2; \
DEBUG_ONLY(assert(reachable_from_branch_at(pc(), dest), "debug only")); \
f(opcode, 31), f(0b00101, 30, 26), sf(offset, 25, 0); \
} \
void NAME(Label &L) { \
wrap_label(L, &Assembler::NAME); \
*** 871,881 ****
#undef INSN
// Compare & branch (immediate)
#define INSN(NAME, opcode) \
void NAME(Register Rt, address dest) { \
! long offset = (dest - pc()) >> 2; \
starti; \
f(opcode, 31, 24), sf(offset, 23, 5), rf(Rt, 0); \
} \
void NAME(Register Rt, Label &L) { \
wrap_label(Rt, L, &Assembler::NAME); \
--- 871,881 ----
#undef INSN
// Compare & branch (immediate)
#define INSN(NAME, opcode) \
void NAME(Register Rt, address dest) { \
! int64_t offset = (dest - pc()) >> 2; \
starti; \
f(opcode, 31, 24), sf(offset, 23, 5), rf(Rt, 0); \
} \
void NAME(Register Rt, Label &L) { \
wrap_label(Rt, L, &Assembler::NAME); \
*** 889,899 ****
#undef INSN
// Test & branch (immediate)
#define INSN(NAME, opcode) \
void NAME(Register Rt, int bitpos, address dest) { \
! long offset = (dest - pc()) >> 2; \
int b5 = bitpos >> 5; \
bitpos &= 0x1f; \
starti; \
f(b5, 31), f(opcode, 30, 24), f(bitpos, 23, 19), sf(offset, 18, 5); \
rf(Rt, 0); \
--- 889,899 ----
#undef INSN
// Test & branch (immediate)
#define INSN(NAME, opcode) \
void NAME(Register Rt, int bitpos, address dest) { \
! int64_t offset = (dest - pc()) >> 2; \
int b5 = bitpos >> 5; \
bitpos &= 0x1f; \
starti; \
f(b5, 31), f(opcode, 30, 24), f(bitpos, 23, 19), sf(offset, 18, 5); \
rf(Rt, 0); \
*** 910,920 ****
// Conditional branch (immediate)
enum Condition
{EQ, NE, HS, CS=HS, LO, CC=LO, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV};
void br(Condition cond, address dest) {
! long offset = (dest - pc()) >> 2;
starti;
f(0b0101010, 31, 25), f(0, 24), sf(offset, 23, 5), f(0, 4), f(cond, 3, 0);
}
#define INSN(NAME, cond) \
--- 910,920 ----
// Conditional branch (immediate)
enum Condition
{EQ, NE, HS, CS=HS, LO, CC=LO, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV};
void br(Condition cond, address dest) {
! int64_t offset = (dest - pc()) >> 2;
starti;
f(0b0101010, 31, 25), f(0, 24), sf(offset, 23, 5), f(0, 4), f(cond, 3, 0);
}
#define INSN(NAME, cond) \
*** 1290,1300 ****
#undef INSN
// Load register (literal)
#define INSN(NAME, opc, V) \
void NAME(Register Rt, address dest) { \
! long offset = (dest - pc()) >> 2; \
starti; \
f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24), \
sf(offset, 23, 5); \
rf(Rt, 0); \
} \
--- 1290,1300 ----
#undef INSN
// Load register (literal)
#define INSN(NAME, opc, V) \
void NAME(Register Rt, address dest) { \
! int64_t offset = (dest - pc()) >> 2; \
starti; \
f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24), \
sf(offset, 23, 5); \
rf(Rt, 0); \
} \
*** 1315,1325 ****
#undef INSN
#define INSN(NAME, opc, V) \
void NAME(FloatRegister Rt, address dest) { \
! long offset = (dest - pc()) >> 2; \
starti; \
f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24), \
sf(offset, 23, 5); \
rf((Register)Rt, 0); \
}
--- 1315,1325 ----
#undef INSN
#define INSN(NAME, opc, V) \
void NAME(FloatRegister Rt, address dest) { \
! int64_t offset = (dest - pc()) >> 2; \
starti; \
f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24), \
sf(offset, 23, 5); \
rf((Register)Rt, 0); \
}
*** 1330,1340 ****
#undef INSN
#define INSN(NAME, opc, V) \
void NAME(address dest, prfop op = PLDL1KEEP) { \
! long offset = (dest - pc()) >> 2; \
starti; \
f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24), \
sf(offset, 23, 5); \
f(op, 4, 0); \
} \
--- 1330,1340 ----
#undef INSN
#define INSN(NAME, opc, V) \
void NAME(address dest, prfop op = PLDL1KEEP) { \
! int64_t offset = (dest - pc()) >> 2; \
starti; \
f(opc, 31, 30), f(0b011, 29, 27), f(V, 26), f(0b00, 25, 24), \
sf(offset, 23, 5); \
f(op, 4, 0); \
} \
*** 1406,1416 ****
// make it worth sharing.
if (adr.getMode() == Address::literal) {
assert(size == 0b10 || size == 0b11, "bad operand size in ldr");
assert(op == 0b01, "literal form can only be used with loads");
f(size & 0b01, 31, 30), f(0b011, 29, 27), f(0b00, 25, 24);
! long offset = (adr.target() - pc()) >> 2;
sf(offset, 23, 5);
code_section()->relocate(pc(), adr.rspec());
return;
}
--- 1406,1416 ----
// make it worth sharing.
if (adr.getMode() == Address::literal) {
assert(size == 0b10 || size == 0b11, "bad operand size in ldr");
assert(op == 0b01, "literal form can only be used with loads");
f(size & 0b01, 31, 30), f(0b011, 29, 27), f(0b00, 25, 24);
! int64_t offset = (adr.target() - pc()) >> 2;
sf(offset, 23, 5);
code_section()->relocate(pc(), adr.rspec());
return;
}
*** 2681,2691 ****
// Stack overflow checking
virtual void bang_stack_with_offset(int offset);
static bool operand_valid_for_logical_immediate(bool is32, uint64_t imm);
! static bool operand_valid_for_add_sub_immediate(long imm);
static bool operand_valid_for_float_immediate(double imm);
void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0);
void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0);
};
--- 2681,2691 ----
// Stack overflow checking
virtual void bang_stack_with_offset(int offset);
static bool operand_valid_for_logical_immediate(bool is32, uint64_t imm);
! static bool operand_valid_for_add_sub_immediate(int64_t imm);
static bool operand_valid_for_float_immediate(double imm);
void emit_data64(jlong data, relocInfo::relocType rtype, int format = 0);
void emit_data64(jlong data, RelocationHolder const& rspec, int format = 0);
};
< prev index next >