Skip to content

Commit

Permalink
restructure
Browse files Browse the repository at this point in the history
  • Loading branch information
robehn committed Nov 14, 2023
1 parent 9335f7b commit 064517b
Showing 1 changed file with 183 additions and 182 deletions.
365 changes: 183 additions & 182 deletions src/hotspot/cpu/riscv/assembler_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2473,189 +2473,8 @@ enum Nf {
INSN(c_ebreak, 0b100, 0b10);

#undef INSN
// -------------- RVC Transformation Functions --------------

// -------------- ZCB Instruction Definitions --------------
// Zcb additional C instructions

template <bool Unsigned>
void c_lh_imp(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
// Format CLH, c.lh/c.lhu
assert_cond(uimm == 0 || uimm == 2);
uint16_t insn = 0;
c_patch((address)&insn, 1, 0, 0b00);
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
c_patch((address)&insn, 6, 6, Unsigned ? 0 : 1);
c_patch_compressed_reg((address)&insn, 7, Rs1);
c_patch((address)&insn, 12, 10, 0b001);
c_patch((address)&insn, 15, 13, 0b100);
emit_int16(insn);
}

template <bool Unsigned>
void lh_imp(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
if (!do_compress() ||
!Rs1->is_compressed_valid() ||
!Rd_Rs2->is_compressed_valid() ||
(uimm != 0 && uimm != 2)) {
if (Unsigned) {
_lhu(Rd_Rs2, Rs1, uimm);
} else {
_lh(Rd_Rs2, Rs1, uimm);
}
} else {
c_lh_imp<Unsigned>(Rd_Rs2, Rs1, uimm);
}
}

void c_lh(Register Rd_Rs2, Register Rs1, const int32_t uimm) { c_lh_imp<false>(Rd_Rs2, Rs1, uimm); }
void c_lhu(Register Rd_Rs2, Register Rs1, const int32_t uimm) { c_lh_imp<true>(Rd_Rs2, Rs1, uimm); }
void lh(Register Rd_Rs2, Register Rs1, const int32_t uimm) { lh_imp<false>(Rd_Rs2, Rs1, uimm); }
void lhu(Register Rd_Rs2, Register Rs1, const int32_t uimm) { lh_imp<true>(Rd_Rs2, Rs1, uimm); }

void c_lbu(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
// Format CLB, single instruction
assert_cond(uimm <= 3);
uint16_t insn = 0;
c_patch((address)&insn, 1, 0, 0b00);
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
c_patch((address)&insn, 6, 6, (uimm & nth_bit(0)) >> 0);
c_patch_compressed_reg((address)&insn, 7, Rs1);
c_patch((address)&insn, 12, 10, 0b000);
c_patch((address)&insn, 15, 13, 0b100);
emit_int16(insn);
}

void lbu(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
if (!do_compress() ||
!Rs1->is_compressed_valid() ||
!Rd_Rs2->is_compressed_valid() ||
uimm < 0 ||
uimm > 3) {
_lbu(Rd_Rs2, Rs1, uimm);
} else {
c_lbu(Rd_Rs2, Rs1, uimm);
}
}

void c_sb(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
// Format CSB, single instruction
assert_cond(uimm <= 3);
uint16_t insn = 0;
c_patch((address)&insn, 1, 0, 0b00);
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
c_patch((address)&insn, 6, 6, (uimm & nth_bit(0)) >> 0);
c_patch_compressed_reg((address)&insn, 7, Rs1);
c_patch((address)&insn, 12, 10, 0b010);
c_patch((address)&insn, 15, 13, 0b100);
emit_int16(insn);
}

void sb(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
if (!do_compress() ||
!Rs1->is_compressed_valid() ||
!Rd_Rs2->is_compressed_valid() ||
uimm < 0 ||
uimm > 3) {
_sb(Rd_Rs2, Rs1, uimm);
} else {
c_sb(Rd_Rs2, Rs1, uimm);
}
}

void c_sh(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
// Format CSH, single instruction
assert_cond(uimm == 0 || uimm == 2);
uint16_t insn = 0;
c_patch((address)&insn, 1, 0, 0b00);
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
c_patch((address)&insn, 6, 6, 0);
c_patch_compressed_reg((address)&insn, 7, Rs1);
c_patch((address)&insn, 12, 10, 0b011);
c_patch((address)&insn, 15, 13, 0b100);
emit_int16(insn);
}

void sh(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
if (!do_compress() ||
!Rs1->is_compressed_valid() ||
!Rd_Rs2->is_compressed_valid() ||
(uimm != 0 && uimm != 2)) {
_sh(Rd_Rs2, Rs1, uimm);
} else {
c_sh(Rd_Rs2, Rs1, uimm);
}
}

template <uint8_t InstructionType>
void c_u_imp(Register Rs1) {
// Format CU, c.[sz]ext.*, c.no
uint16_t insn = 0;
c_patch((address)&insn, 1, 0, 0b01);
c_patch((address)&insn, 4, 2, InstructionType);
c_patch((address)&insn, 6, 5, 0b11);
c_patch_compressed_reg((address)&insn, 7, Rs1);
c_patch((address)&insn, 12, 10, 0b111);
c_patch((address)&insn, 15, 13, 0b101);
emit_int16(insn);
}

void c_zext_b(Register Rs1) {
c_u_imp<0b000>(Rs1);
}

void c_sext_b(Register Rs1) {
c_u_imp<0b001>(Rs1);
}

void c_zext_h(Register Rs1) {
c_u_imp<0b010>(Rs1);
}

void c_sext_h(Register Rs1) {
c_u_imp<0b011>(Rs1);
}

void c_zext_w(Register Rs1) {
c_u_imp<0b100>(Rs1);
}

void c_not(Register Rs1) {
c_u_imp<0b101>(Rs1);
}

void c_mul(Register Rd_Rs1, Register Rs2) {
// Format CA, c.mul and others
uint16_t insn = 0;
c_patch((address)&insn, 1, 0, 0b01);
c_patch_compressed_reg((address)&insn, 2, Rs2);
c_patch((address)&insn, 6, 5, 0b10);
c_patch_compressed_reg((address)&insn, 7, Rd_Rs1);
c_patch((address)&insn, 12, 10, 0b111);
c_patch((address)&insn, 15, 13, 0b100);
emit_int16(insn);
}

void mul(Register Rd, Register Rs1, Register Rs2) {
if (Rd != Rs1 && Rd != Rs2) {
_mul(Rd, Rs1, Rs2);
return;
}
if (!do_compress() ||
!Rs1->is_compressed_valid() ||
!Rs2->is_compressed_valid()) {
_mul(Rd, Rs1, Rs2);
} else {
if (Rd == Rs2) {
Rs2 = Rs1;
}
c_mul(Rd, Rs2);
}
}
// -------------- RVC Transformation Functions --------------

// --------------------------
// Register instructions
Expand Down Expand Up @@ -3095,6 +2914,188 @@ enum Nf {

#undef INSN

// -------------- ZCB Instruction Definitions --------------
// Zcb additional C instructions

template <bool Unsigned>
void c_lh_imp(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
// Format CLH, c.lh/c.lhu
assert_cond(uimm == 0 || uimm == 2);
uint16_t insn = 0;
c_patch((address)&insn, 1, 0, 0b00);
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
c_patch((address)&insn, 6, 6, Unsigned ? 0 : 1);
c_patch_compressed_reg((address)&insn, 7, Rs1);
c_patch((address)&insn, 12, 10, 0b001);
c_patch((address)&insn, 15, 13, 0b100);
emit_int16(insn);
}

template <bool Unsigned>
void lh_imp(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
if (!do_compress() ||
!Rs1->is_compressed_valid() ||
!Rd_Rs2->is_compressed_valid() ||
(uimm != 0 && uimm != 2)) {
if (Unsigned) {
_lhu(Rd_Rs2, Rs1, uimm);
} else {
_lh(Rd_Rs2, Rs1, uimm);
}
} else {
c_lh_imp<Unsigned>(Rd_Rs2, Rs1, uimm);
}
}

void c_lh(Register Rd_Rs2, Register Rs1, const int32_t uimm) { c_lh_imp<false>(Rd_Rs2, Rs1, uimm); }
void c_lhu(Register Rd_Rs2, Register Rs1, const int32_t uimm) { c_lh_imp<true>(Rd_Rs2, Rs1, uimm); }
void lh(Register Rd_Rs2, Register Rs1, const int32_t uimm) { lh_imp<false>(Rd_Rs2, Rs1, uimm); }
void lhu(Register Rd_Rs2, Register Rs1, const int32_t uimm) { lh_imp<true>(Rd_Rs2, Rs1, uimm); }

void c_lbu(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
// Format CLB, single instruction
assert_cond(uimm <= 3);
uint16_t insn = 0;
c_patch((address)&insn, 1, 0, 0b00);
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
c_patch((address)&insn, 6, 6, (uimm & nth_bit(0)) >> 0);
c_patch_compressed_reg((address)&insn, 7, Rs1);
c_patch((address)&insn, 12, 10, 0b000);
c_patch((address)&insn, 15, 13, 0b100);
emit_int16(insn);
}

void lbu(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
if (!do_compress() ||
!Rs1->is_compressed_valid() ||
!Rd_Rs2->is_compressed_valid() ||
uimm < 0 ||
uimm > 3) {
_lbu(Rd_Rs2, Rs1, uimm);
} else {
c_lbu(Rd_Rs2, Rs1, uimm);
}
}

void c_sb(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
// Format CSB, single instruction
assert_cond(uimm <= 3);
uint16_t insn = 0;
c_patch((address)&insn, 1, 0, 0b00);
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
c_patch((address)&insn, 6, 6, (uimm & nth_bit(0)) >> 0);
c_patch_compressed_reg((address)&insn, 7, Rs1);
c_patch((address)&insn, 12, 10, 0b010);
c_patch((address)&insn, 15, 13, 0b100);
emit_int16(insn);
}

void sb(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
if (!do_compress() ||
!Rs1->is_compressed_valid() ||
!Rd_Rs2->is_compressed_valid() ||
uimm < 0 ||
uimm > 3) {
_sb(Rd_Rs2, Rs1, uimm);
} else {
c_sb(Rd_Rs2, Rs1, uimm);
}
}

void c_sh(Register Rd_Rs2, Register Rs1, uint32_t uimm) {
// Format CSH, single instruction
assert_cond(uimm == 0 || uimm == 2);
uint16_t insn = 0;
c_patch((address)&insn, 1, 0, 0b00);
c_patch_compressed_reg((address)&insn, 2, Rd_Rs2);
c_patch((address)&insn, 5, 5, (uimm & nth_bit(1)) >> 1);
c_patch((address)&insn, 6, 6, 0);
c_patch_compressed_reg((address)&insn, 7, Rs1);
c_patch((address)&insn, 12, 10, 0b011);
c_patch((address)&insn, 15, 13, 0b100);
emit_int16(insn);
}

void sh(Register Rd_Rs2, Register Rs1, const int32_t uimm) {
if (!do_compress() ||
!Rs1->is_compressed_valid() ||
!Rd_Rs2->is_compressed_valid() ||
(uimm != 0 && uimm != 2)) {
_sh(Rd_Rs2, Rs1, uimm);
} else {
c_sh(Rd_Rs2, Rs1, uimm);
}
}

template <uint8_t InstructionType>
void c_u_imp(Register Rs1) {
// Format CU, c.[sz]ext.*, c.no
uint16_t insn = 0;
c_patch((address)&insn, 1, 0, 0b01);
c_patch((address)&insn, 4, 2, InstructionType);
c_patch((address)&insn, 6, 5, 0b11);
c_patch_compressed_reg((address)&insn, 7, Rs1);
c_patch((address)&insn, 12, 10, 0b111);
c_patch((address)&insn, 15, 13, 0b101);
emit_int16(insn);
}

void c_zext_b(Register Rs1) {
c_u_imp<0b000>(Rs1);
}

void c_sext_b(Register Rs1) {
c_u_imp<0b001>(Rs1);
}

void c_zext_h(Register Rs1) {
c_u_imp<0b010>(Rs1);
}

void c_sext_h(Register Rs1) {
c_u_imp<0b011>(Rs1);
}

void c_zext_w(Register Rs1) {
c_u_imp<0b100>(Rs1);
}

void c_not(Register Rs1) {
c_u_imp<0b101>(Rs1);
}

void c_mul(Register Rd_Rs1, Register Rs2) {
// Format CA, c.mul and others
uint16_t insn = 0;
c_patch((address)&insn, 1, 0, 0b01);
c_patch_compressed_reg((address)&insn, 2, Rs2);
c_patch((address)&insn, 6, 5, 0b10);
c_patch_compressed_reg((address)&insn, 7, Rd_Rs1);
c_patch((address)&insn, 12, 10, 0b111);
c_patch((address)&insn, 15, 13, 0b100);
emit_int16(insn);
}

void mul(Register Rd, Register Rs1, Register Rs2) {
if (Rd != Rs1 && Rd != Rs2) {
_mul(Rd, Rs1, Rs2);
return;
}
if (!do_compress() ||
!Rs1->is_compressed_valid() ||
!Rs2->is_compressed_valid()) {
_mul(Rd, Rs1, Rs2);
} else {
if (Rd == Rs2) {
Rs2 = Rs1;
}
c_mul(Rd, Rs2);
}
}

// Stack overflow checking
virtual void bang_stack_with_offset(int offset) { Unimplemented(); }

Expand Down

0 comments on commit 064517b

Please sign in to comment.