Skip to content

Commit dc96160

Browse files
committed
8356159: RISC-V: Add Zabha
Reviewed-by: fyang, fjiang
1 parent 7838321 commit dc96160

File tree

6 files changed

+764
-265
lines changed

6 files changed

+764
-265
lines changed

src/hotspot/cpu/riscv/assembler_riscv.hpp

Lines changed: 231 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -961,81 +961,239 @@ class Assembler : public AbstractAssembler {
961961

962962
#undef INSN
963963

964-
enum Aqrl {relaxed = 0b00, rl = 0b01, aq = 0b10, aqrl = 0b11};
965-
966-
#define INSN(NAME, op, funct3, funct7) \
967-
void NAME(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) { \
968-
unsigned insn = 0; \
969-
patch((address)&insn, 6, 0, op); \
970-
patch((address)&insn, 14, 12, funct3); \
971-
patch_reg((address)&insn, 7, Rd); \
972-
patch_reg((address)&insn, 15, Rs1); \
973-
patch_reg((address)&insn, 20, Rs2); \
974-
patch((address)&insn, 31, 27, funct7); \
975-
patch((address)&insn, 26, 25, memory_order); \
976-
emit(insn); \
977-
}
978-
979-
INSN(amoswap_w, 0b0101111, 0b010, 0b00001);
980-
INSN(amoadd_w, 0b0101111, 0b010, 0b00000);
981-
INSN(amoxor_w, 0b0101111, 0b010, 0b00100);
982-
INSN(amoand_w, 0b0101111, 0b010, 0b01100);
983-
INSN(amoor_w, 0b0101111, 0b010, 0b01000);
984-
INSN(amomin_w, 0b0101111, 0b010, 0b10000);
985-
INSN(amomax_w, 0b0101111, 0b010, 0b10100);
986-
INSN(amominu_w, 0b0101111, 0b010, 0b11000);
987-
INSN(amomaxu_w, 0b0101111, 0b010, 0b11100);
988-
INSN(amoswap_d, 0b0101111, 0b011, 0b00001);
989-
INSN(amoadd_d, 0b0101111, 0b011, 0b00000);
990-
INSN(amoxor_d, 0b0101111, 0b011, 0b00100);
991-
INSN(amoand_d, 0b0101111, 0b011, 0b01100);
992-
INSN(amoor_d, 0b0101111, 0b011, 0b01000);
993-
INSN(amomin_d, 0b0101111, 0b011, 0b10000);
994-
INSN(amomax_d , 0b0101111, 0b011, 0b10100);
995-
INSN(amominu_d, 0b0101111, 0b011, 0b11000);
996-
INSN(amomaxu_d, 0b0101111, 0b011, 0b11100);
997-
INSN(amocas_w, 0b0101111, 0b010, 0b00101);
998-
INSN(amocas_d, 0b0101111, 0b011, 0b00101);
999-
#undef INSN
1000-
1001-
enum operand_size { int8, int16, int32, uint32, int64 };
1002-
1003-
#define INSN(NAME, op, funct3, funct7) \
1004-
void NAME(Register Rd, Register Rs1, Aqrl memory_order = relaxed) { \
1005-
unsigned insn = 0; \
1006-
uint32_t val = memory_order & 0x3; \
1007-
patch((address)&insn, 6, 0, op); \
1008-
patch((address)&insn, 14, 12, funct3); \
1009-
patch_reg((address)&insn, 7, Rd); \
1010-
patch_reg((address)&insn, 15, Rs1); \
1011-
patch((address)&insn, 25, 20, 0b00000); \
1012-
patch((address)&insn, 31, 27, funct7); \
1013-
patch((address)&insn, 26, 25, val); \
1014-
emit(insn); \
1015-
}
1016-
1017-
INSN(lr_w, 0b0101111, 0b010, 0b00010);
1018-
INSN(lr_d, 0b0101111, 0b011, 0b00010);
1019-
1020-
#undef INSN
1021-
1022-
#define INSN(NAME, op, funct3, funct7) \
1023-
void NAME(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = relaxed) { \
1024-
unsigned insn = 0; \
1025-
uint32_t val = memory_order & 0x3; \
1026-
patch((address)&insn, 6, 0, op); \
1027-
patch((address)&insn, 14, 12, funct3); \
1028-
patch_reg((address)&insn, 7, Rd); \
1029-
patch_reg((address)&insn, 15, Rs2); \
1030-
patch_reg((address)&insn, 20, Rs1); \
1031-
patch((address)&insn, 31, 27, funct7); \
1032-
patch((address)&insn, 26, 25, val); \
1033-
emit(insn); \
964+
enum Aqrl {relaxed = 0b00, rl = 0b01, aq = 0b10, aqrl = 0b11};
965+
966+
private:
967+
968+
enum AmoWidthFunct3 : uint8_t {
969+
AMO_WIDTH_BYTE = 0b000, // Zabha extension
970+
AMO_WIDTH_HALFWORD = 0b001, // Zabha extension
971+
AMO_WIDTH_WORD = 0b010,
972+
AMO_WIDTH_DOUBLEWORD = 0b011,
973+
AMO_WIDTH_QUADWORD = 0b100,
974+
// 0b101 to 0b111 are reserved
975+
};
976+
977+
enum AmoOperationFunct5 : uint8_t {
978+
AMO_ADD = 0b00000,
979+
AMO_SWAP = 0b00001,
980+
AMO_LR = 0b00010,
981+
AMO_SC = 0b00011,
982+
AMO_XOR = 0b00100,
983+
AMO_OR = 0b01000,
984+
AMO_AND = 0b01100,
985+
AMO_MIN = 0b10000,
986+
AMO_MAX = 0b10100,
987+
AMO_MINU = 0b11000,
988+
AMO_MAXU = 0b11100,
989+
AMO_CAS = 0b00101 // Zacas
990+
};
991+
992+
static constexpr uint32_t OP_AMO_MAJOR = 0b0101111;
993+
994+
template <AmoOperationFunct5 funct5, AmoWidthFunct3 width>
995+
void amo_base(Register Rd, Register Rs1, uint8_t Rs2, Aqrl memory_order = aqrl) {
996+
assert(width > AMO_WIDTH_HALFWORD || UseZabha, "Must be");
997+
assert(funct5 != AMO_CAS || UseZacas, "Must be");
998+
unsigned insn = 0;
999+
patch((address)&insn, 6, 0, OP_AMO_MAJOR);
1000+
patch_reg((address)&insn, 7, Rd);
1001+
patch((address)&insn, 14, 12, width);
1002+
patch_reg((address)&insn, 15, Rs1);
1003+
patch((address)&insn, 24, 20, Rs2);
1004+
patch((address)&insn, 26, 25, memory_order);
1005+
patch((address)&insn, 31, 27, funct5);
1006+
emit(insn);
10341007
}
10351008

1036-
INSN(sc_w, 0b0101111, 0b010, 0b00011);
1037-
INSN(sc_d, 0b0101111, 0b011, 0b00011);
1038-
#undef INSN
1009+
template <AmoOperationFunct5 funct5, AmoWidthFunct3 width>
1010+
void amo_base(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1011+
amo_base<funct5, width>(Rd, Rs1, Rs2->raw_encoding(), memory_order);
1012+
}
1013+
1014+
public:
1015+
1016+
void amoadd_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1017+
amo_base<AMO_ADD, AMO_WIDTH_BYTE>(Rd, Rs1, Rs2, memory_order);
1018+
}
1019+
1020+
void amoadd_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1021+
amo_base<AMO_ADD, AMO_WIDTH_HALFWORD>(Rd, Rs1, Rs2, memory_order);
1022+
}
1023+
1024+
void amoadd_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1025+
amo_base<AMO_ADD, AMO_WIDTH_WORD>(Rd, Rs1, Rs2, memory_order);
1026+
}
1027+
1028+
void amoadd_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1029+
amo_base<AMO_ADD, AMO_WIDTH_DOUBLEWORD>(Rd, Rs1, Rs2, memory_order);
1030+
}
1031+
1032+
void amoswap_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1033+
amo_base<AMO_SWAP, AMO_WIDTH_BYTE>(Rd, Rs1, Rs2, memory_order);
1034+
}
1035+
1036+
void amoswap_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1037+
amo_base<AMO_SWAP, AMO_WIDTH_HALFWORD>(Rd, Rs1, Rs2, memory_order);
1038+
}
1039+
1040+
void amoswap_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1041+
amo_base<AMO_SWAP, AMO_WIDTH_WORD>(Rd, Rs1, Rs2, memory_order);
1042+
}
1043+
1044+
void amoswap_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1045+
amo_base<AMO_SWAP, AMO_WIDTH_DOUBLEWORD>(Rd, Rs1, Rs2, memory_order);
1046+
}
1047+
1048+
void amoxor_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1049+
amo_base<AMO_XOR, AMO_WIDTH_BYTE>(Rd, Rs1, Rs2, memory_order);
1050+
}
1051+
1052+
void amoxor_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1053+
amo_base<AMO_XOR, AMO_WIDTH_HALFWORD>(Rd, Rs1, Rs2, memory_order);
1054+
}
1055+
1056+
void amoxor_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1057+
amo_base<AMO_XOR, AMO_WIDTH_WORD>(Rd, Rs1, Rs2, memory_order);
1058+
}
1059+
1060+
void amoxor_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1061+
amo_base<AMO_XOR, AMO_WIDTH_DOUBLEWORD>(Rd, Rs1, Rs2, memory_order);
1062+
}
1063+
1064+
void amoor_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1065+
amo_base<AMO_OR, AMO_WIDTH_BYTE>(Rd, Rs1, Rs2, memory_order);
1066+
}
1067+
1068+
void amoor_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1069+
amo_base<AMO_OR, AMO_WIDTH_HALFWORD>(Rd, Rs1, Rs2, memory_order);
1070+
}
1071+
1072+
void amoor_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1073+
amo_base<AMO_OR, AMO_WIDTH_WORD>(Rd, Rs1, Rs2, memory_order);
1074+
}
1075+
1076+
void amoor_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1077+
amo_base<AMO_OR, AMO_WIDTH_DOUBLEWORD>(Rd, Rs1, Rs2, memory_order);
1078+
}
1079+
1080+
void amoand_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1081+
amo_base<AMO_AND, AMO_WIDTH_BYTE>(Rd, Rs1, Rs2, memory_order);
1082+
}
1083+
1084+
void amoand_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1085+
amo_base<AMO_AND, AMO_WIDTH_HALFWORD>(Rd, Rs1, Rs2, memory_order);
1086+
}
1087+
1088+
void amoand_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1089+
amo_base<AMO_AND, AMO_WIDTH_WORD>(Rd, Rs1, Rs2, memory_order);
1090+
}
1091+
1092+
void amoand_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1093+
amo_base<AMO_AND, AMO_WIDTH_DOUBLEWORD>(Rd, Rs1, Rs2, memory_order);
1094+
}
1095+
1096+
void amomin_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1097+
amo_base<AMO_MIN, AMO_WIDTH_BYTE>(Rd, Rs1, Rs2, memory_order);
1098+
}
1099+
1100+
void amomin_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1101+
amo_base<AMO_MIN, AMO_WIDTH_HALFWORD>(Rd, Rs1, Rs2, memory_order);
1102+
}
1103+
1104+
void amomin_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1105+
amo_base<AMO_MIN, AMO_WIDTH_WORD>(Rd, Rs1, Rs2, memory_order);
1106+
}
1107+
1108+
void amomin_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1109+
amo_base<AMO_MIN, AMO_WIDTH_DOUBLEWORD>(Rd, Rs1, Rs2, memory_order);
1110+
}
1111+
1112+
void amominu_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1113+
amo_base<AMO_MINU, AMO_WIDTH_BYTE>(Rd, Rs1, Rs2, memory_order);
1114+
}
1115+
1116+
void amominu_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1117+
amo_base<AMO_MINU, AMO_WIDTH_HALFWORD>(Rd, Rs1, Rs2, memory_order);
1118+
}
1119+
1120+
void amominu_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1121+
amo_base<AMO_MINU, AMO_WIDTH_WORD>(Rd, Rs1, Rs2, memory_order);
1122+
}
1123+
1124+
void amominu_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1125+
amo_base<AMO_MINU, AMO_WIDTH_DOUBLEWORD>(Rd, Rs1, Rs2, memory_order);
1126+
}
1127+
1128+
void amomax_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1129+
amo_base<AMO_MAX, AMO_WIDTH_BYTE>(Rd, Rs1, Rs2, memory_order);
1130+
}
1131+
1132+
void amomax_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1133+
amo_base<AMO_MAX, AMO_WIDTH_HALFWORD>(Rd, Rs1, Rs2, memory_order);
1134+
}
1135+
1136+
void amomax_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1137+
amo_base<AMO_MAX, AMO_WIDTH_WORD>(Rd, Rs1, Rs2, memory_order);
1138+
}
1139+
1140+
void amomax_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1141+
amo_base<AMO_MAX, AMO_WIDTH_DOUBLEWORD>(Rd, Rs1, Rs2, memory_order);
1142+
}
1143+
1144+
void amomaxu_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1145+
amo_base<AMO_MAXU, AMO_WIDTH_BYTE>(Rd, Rs1, Rs2, memory_order);
1146+
}
1147+
1148+
void amomaxu_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1149+
amo_base<AMO_MAXU, AMO_WIDTH_HALFWORD>(Rd, Rs1, Rs2, memory_order);
1150+
}
1151+
1152+
void amomaxu_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1153+
amo_base<AMO_MAXU, AMO_WIDTH_WORD>(Rd, Rs1, Rs2, memory_order);
1154+
}
1155+
1156+
void amomaxu_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1157+
amo_base<AMO_MAXU, AMO_WIDTH_DOUBLEWORD>(Rd, Rs1, Rs2, memory_order);
1158+
}
1159+
1160+
protected:
1161+
1162+
void lr_w(Register Rd, Register Rs1, Aqrl memory_order = aqrl) {
1163+
amo_base<AMO_LR, AMO_WIDTH_WORD>(Rd, Rs1, 0, memory_order);
1164+
}
1165+
1166+
void lr_d(Register Rd, Register Rs1, Aqrl memory_order = aqrl) {
1167+
amo_base<AMO_LR, AMO_WIDTH_DOUBLEWORD>(Rd, Rs1, 0, memory_order);
1168+
}
1169+
1170+
void sc_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1171+
amo_base<AMO_SC, AMO_WIDTH_WORD>(Rd, Rs1, Rs2, memory_order);
1172+
}
1173+
1174+
void sc_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1175+
amo_base<AMO_SC, AMO_WIDTH_DOUBLEWORD>(Rd, Rs1, Rs2, memory_order);
1176+
}
1177+
1178+
void amocas_b(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1179+
amo_base<AMO_CAS, AMO_WIDTH_BYTE>(Rd, Rs1, Rs2, memory_order);
1180+
}
1181+
1182+
void amocas_h(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1183+
amo_base<AMO_CAS, AMO_WIDTH_HALFWORD>(Rd, Rs1, Rs2, memory_order);
1184+
}
1185+
1186+
void amocas_w(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1187+
amo_base<AMO_CAS, AMO_WIDTH_WORD>(Rd, Rs1, Rs2, memory_order);
1188+
}
1189+
1190+
void amocas_d(Register Rd, Register Rs1, Register Rs2, Aqrl memory_order = aqrl) {
1191+
amo_base<AMO_CAS, AMO_WIDTH_DOUBLEWORD>(Rd, Rs1, Rs2, memory_order);
1192+
}
1193+
1194+
public:
1195+
1196+
enum operand_size { int8, int16, int32, uint32, int64 };
10391197

10401198
// Immediate Instruction
10411199
#define INSN(NAME, op, funct3) \

src/hotspot/cpu/riscv/globals_riscv.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ define_pd_global(intx, InlineSmallCode, 1000);
107107
product(bool, UseZfh, false, DIAGNOSTIC, "Use Zfh instructions") \
108108
product(bool, UseZfhmin, false, DIAGNOSTIC, "Use Zfhmin instructions") \
109109
product(bool, UseZacas, false, EXPERIMENTAL, "Use Zacas instructions") \
110+
product(bool, UseZabha, false, EXPERIMENTAL, "Use UseZabha instructions") \
110111
product(bool, UseZcb, false, EXPERIMENTAL, "Use Zcb instructions") \
111112
product(bool, UseZic64b, false, EXPERIMENTAL, "Use Zic64b instructions") \
112113
product(bool, UseZicbom, false, EXPERIMENTAL, "Use Zicbom instructions") \

0 commit comments

Comments
 (0)